﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;
using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows.Printing;
using System.Globalization;

namespace Gmantis.Controls.DataGrid
{
    public enum DataGridColumnFreezing
    {
        None,
        Left
    }

    [Flags]
    public enum DataGridClipboardMode
    {
        ExcludeHeader = 1,
        IncludeAllHeaders = 7,
        IncludeColumnHeaders = 3,
        IncludeRowHeaders = 5,
        None = 0
    }

    [Flags]
    public enum DataGridHeadersVisibility
    {
        None,
        Column,
        Row,
        All
    }

    public enum DataGridRowDetailsVisibilityMode
    {
        VisibleWhenSelected,
        Visible,
        Collapsed
    }

    public enum DataGridScrollMode
    {
        RealTime,
        Deferred
    }

    public enum DataGridScrollStepUnitType
    {
        Discrete,
        Pixel
    }

    public enum ScaleMode
    {
        ActualSize,
        PageWidth,
        SinglePage
    }

    [StyleTypedProperty(Property = "DragSourceColumnStyle", StyleTargetType = typeof(ContentControl)), 
    TemplatePart(Name = "RowsHeader", Type = typeof(DataGridRowsHeaderPanel)), 
    TemplatePart(Name = "Root", Type = typeof(Grid)), TemplatePart(Name = "Grouping", Type = typeof(DataGridGroupingPresenter)), 
    TemplatePart(Name = "TopLeftCorner", Type = typeof(Button)), TemplatePart(Name = "Popup", Type = typeof(Popup)), 
    TemplateVisualState(Name = "Loading", GroupName = "LoadingStates"), TemplateVisualState(Name = "Ready", GroupName = "LoadingStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"), TemplatePart(Name = "VerticalScrollBar", Type = typeof(ScrollBar)), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), 
    StyleTypedProperty(Property = "RowStyle", StyleTargetType = typeof(DataGridRowPresenter)), 
    StyleTypedProperty(Property = "NewRowStyle", StyleTargetType = typeof(DataGridNewRowPresenter)), 
    StyleTypedProperty(Property = "RowHeaderStyle", StyleTargetType = typeof(DataGridRowHeaderPresenter)), 
    StyleTypedProperty(Property = "NewRowHeaderStyle", StyleTargetType = typeof(DataGridNewRowHeaderPresenter)), 
    StyleTypedProperty(Property = "FocusStyle", StyleTargetType = typeof(DataGridFocusPresenter)), 
    StyleTypedProperty(Property = "CellStyle", StyleTargetType = typeof(DataGridCellPresenter)), 
    StyleTypedProperty(Property = "ColumnHeaderStyle", StyleTargetType = typeof(DataGridColumnHeaderPresenter)), 
    StyleTypedProperty(Property = "GroupColumnHeaderStyle", StyleTargetType = typeof(DataGridGroupColumnHeaderPresenter)), 
    StyleTypedProperty(Property = "DropIndicatorStyle", StyleTargetType = typeof(ContentControl)), 
    StyleTypedProperty(Property = "DragOverColumnStyle", StyleTargetType = typeof(ContentControl)), 
    StyleTypedProperty(Property = "FilterStyle", StyleTargetType = typeof(DataGridFilter)), 
    StyleTypedProperty(Property = "GroupRowStyle", StyleTargetType = typeof(DataGridGroupRowPresenter)), 
    StyleTypedProperty(Property = "GroupRowHeaderStyle", StyleTargetType = typeof(DataGridRowHeaderPresenter)), 
    StyleTypedProperty(Property = "VerticalFreezingSeparatorStyle", StyleTargetType = typeof(DataGridVerticalFreezingSeparatorPresenter)), 
    StyleTypedProperty(Property = "ScrollBarStyle", StyleTargetType = typeof(ScrollBar)), 
    StyleTypedProperty(Property = "GroupingPanelStyle", StyleTargetType = typeof(DataGridGroupingPresenter)), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplatePart(Name = "ColumnsHeader", Type = typeof(DataGridColumnsHeaderPanel)), TemplatePart(Name = "Body", Type = typeof(DataGridRowsPanel)), 
    TemplatePart(Name = "HorizontalScrollBar", Type = typeof(ScrollBar))]
    public class DataGrid : Control, ISupportInitialize, INotifyPropertyChanged
    {
        // Fields
        internal DataGridRowsPanel _elementBody;
        internal DataGridColumnsHeaderPanel _elementColumnsHeader;
        internal DataGridGroupingPresenter _elementGrouping;
        internal ScrollBar _elementHorizontalScrollBar;
        internal Popup _elementPopup;
        internal Grid _elementRoot;
        internal DataGridRowsHeaderPanel _elementRowsHeader;
        internal Button _elementTopLeftCorner;
        internal ScrollBar _elementVerticalScrollBar;
        private bool _isEditing;
        internal bool _isLoaded;
        private Rectangle _rectOverlay;
        private bool _throwFrozenBottomRowsCountChanged;
        private bool _throwFrozenColumnCountChanged;
        private bool _throwFrozenTopRowsCountChanged;
        private bool _throwIsLoadingChanged;
        private bool _throwIsMouseOverChanged;
        private bool _throwLeadingColumnWidthChanged;
        internal static readonly DependencyProperty ActualShowGroupingPanelProperty = DependencyProperty.Register("ActualShowGroupingPanel", typeof(bool), typeof(DataGrid), new PropertyMetadata(false));
        public static readonly DependencyProperty AlternatingRowBackgroundProperty = DependencyProperty.Register("AlternatingRowBackground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnAlternatingRowBackgroundPropertyChanged)));
        public static readonly DependencyProperty AlternatingRowForegroundProperty = DependencyProperty.Register("AlternatingRowForeground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnAlternatingRowForegroundPropertyChanged)));
        public static readonly DependencyProperty AutoGenerateColumnsProperty = DependencyProperty.Register("AutoGenerateColumns", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnAutoGenerateColumnsPropertyChanged)));
        internal const string BodyElementName = "Body";
        public static readonly DependencyProperty BodyRectProperty = DependencyProperty.Register("BodyRect", typeof(Rect), typeof(DataGrid), null);
        public static readonly DependencyProperty CanUserAddRowsProperty = DependencyProperty.Register("CanUserAddRows", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserAddRowsPropertyChanged)));
        public static readonly DependencyProperty CanUserEditRowsProperty = DependencyProperty.Register("CanUserEditRows", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserEditRowsPropertyChanged)));
        public static readonly DependencyProperty CanUserFilterProperty = DependencyProperty.Register("CanUserFilter", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserFilterPropertyChanged)));
        public static readonly DependencyProperty CanUserFreezeColumnsProperty = DependencyProperty.Register("CanUserFreezeColumns", typeof(DataGridColumnFreezing), typeof(DataGrid), new PropertyMetadata(DataGridColumnFreezing.None, new PropertyChangedCallback(DataGrid.OnCanUserFreezeColumnsPropertyChanged)));
        public static readonly DependencyProperty CanUserGroupProperty = DependencyProperty.Register("CanUserGroup", typeof(bool), typeof(DataGrid), new PropertyMetadata(false, new PropertyChangedCallback(DataGrid.OnCanUserGroupPropertyChanged)));
        public static readonly DependencyProperty CanUserRemoveRowsProperty = DependencyProperty.Register("CanUserRemoveRows", typeof(bool), typeof(DataGrid), new PropertyMetadata(true));
        public static readonly DependencyProperty CanUserReorderColumnsProperty = DependencyProperty.Register("CanUserReorderColumns", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserReorderColumnsPropertyChanged)));
        public static readonly DependencyProperty CanUserResizeColumnsProperty = DependencyProperty.Register("CanUserResizeColumns", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserResizeColumnsPropertyChanged)));
        public static readonly DependencyProperty CanUserResizeRowsProperty = DependencyProperty.Register("CanUserResizeRows", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserResizeRowsPropertyChanged)));
        public static readonly DependencyProperty CanUserSelectByDraggingProperty = DependencyProperty.Register("CanUserSelectByDragging", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserSelectByDraggingPropertyChanged)));
        public static readonly DependencyProperty CanUserSortProperty = DependencyProperty.Register("CanUserSort", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnCanUserSortPropertyChanged)));
        public static readonly DependencyProperty CanUserToggleDetailsProperty = DependencyProperty.Register("CanUserToggleDetails", typeof(bool), typeof(DataGrid), new PropertyMetadata(true));
        public static readonly DependencyProperty CellStyleProperty = DependencyProperty.Register("CellStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnCellStylePropertyChanged)));
        public static readonly DependencyProperty ClipboardCopyModeProperty = DependencyProperty.Register("ClipboardCopyMode", typeof(DataGridClipboardMode), typeof(DataGrid), new PropertyMetadata(DataGridClipboardMode.ExcludeHeader));
        public static readonly DependencyProperty ClipboardPasteModeProperty = DependencyProperty.Register("ClipboardPasteMode", typeof(DataGridClipboardMode), typeof(DataGrid), new PropertyMetadata(DataGridClipboardMode.ExcludeHeader));
        public static readonly DependencyProperty ColumnHeaderClickActionProperty = DependencyProperty.Register("ColumnHeaderClickAction", typeof(DataGridColumnHeaderClickAction), typeof(DataGrid), new PropertyMetadata(DataGridColumnHeaderClickAction.Sort));
        public static readonly DependencyProperty ColumnHeaderHeightProperty = DependencyProperty.Register("ColumnHeaderHeight", typeof(double), typeof(DataGrid), new PropertyMetadata(24.0, new PropertyChangedCallback(DataGrid.OnColumnHeaderHeightPropertyChanged)));
        public static readonly DependencyProperty ColumnHeaderOptionsVisibilityProperty = DependencyProperty.Register("ColumnHeaderOptionsVisibility", typeof(DataGridOptionsVisibility), typeof(DataGrid), new PropertyMetadata(DataGridOptionsVisibility.OnMouseOver));
        public static readonly DependencyProperty ColumnHeaderStyleProperty = DependencyProperty.Register("ColumnHeaderStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnColumnHeaderStylePropertyChanged)));
        internal const string ColumnsHeaderElementName = "ColumnsHeader";
        public static readonly DependencyProperty ColumnWidthProperty = DependencyProperty.Register("ColumnWidth", typeof(DataGridLength), typeof(DataGrid), new PropertyMetadata(new DataGridLength(1.0, DataGridUnitType.AutoStar), new PropertyChangedCallback(DataGrid.OnColumnWidthPropertyChanged)));
        public static readonly DependencyProperty CurrentColumnProperty = DependencyProperty.Register("CurrentColumn", typeof(DataGridColumn), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnCurrentColumnPropertyChanged)));
        public static readonly DependencyProperty CurrentRowProperty = DependencyProperty.Register("CurrentRow", typeof(DataGridRow), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnCurrentRowPropertyChanged)));
        public static readonly DependencyProperty DragOverColumnStyleProperty = DependencyProperty.Register("DragOverColumnStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnDragOverColumnStylePropertyChanged)));
        public static readonly DependencyProperty DragSourceColumnStyleProperty = DependencyProperty.Register("DragSourceColumnStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnDragSourceColumnStylePropertyChanged)));
        public static readonly DependencyProperty DropIndicatorStyleProperty = DependencyProperty.Register("DropIndicatorStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnDropIndicatorStylePropertyChanged)));
        public static readonly DependencyProperty FiltersCombinationProperty = DependencyProperty.Register("FiltersCombination", typeof(DataGridFilterCombination), typeof(DataGrid), new PropertyMetadata(DataGridFilterCombination.And));
        public static readonly DependencyProperty FilterStyleProperty = DependencyProperty.Register("FilterStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnFilterStylePropertyChanged)));
        public static readonly DependencyProperty FocusStyleProperty = DependencyProperty.Register("FocusStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnFocusStylePropertyChanged)));
        internal static readonly DependencyProperty ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnForceMouseOverPropertyChanged)));
        public static readonly DependencyProperty FrozenBottomRowsCountProperty = DependencyProperty.Register("FrozenBottomRowsCount", typeof(int), typeof(DataGrid), new PropertyMetadata(0, new PropertyChangedCallback(DataGrid.OnFrozenBottomRowsCountPropertyChanged)));
        public static readonly DependencyProperty FrozenColumnCountProperty = DependencyProperty.Register("FrozenColumnCount", typeof(int), typeof(DataGrid), new PropertyMetadata(0, new PropertyChangedCallback(DataGrid.OnFrozenColumnCountPropertyChanged)));
        public static readonly DependencyProperty FrozenTopRowsCountProperty = DependencyProperty.Register("FrozenTopRowsCount", typeof(int), typeof(DataGrid), new PropertyMetadata(0, new PropertyChangedCallback(DataGrid.OnFrozenTopRowsCountPropertyChanged)));
        public static readonly DependencyProperty GridLinesVisibilityProperty = DependencyProperty.Register("GridLinesVisibility", typeof(DataGridGridLinesVisibility), typeof(DataGrid), new PropertyMetadata(DataGridGridLinesVisibility.Vertical, new PropertyChangedCallback(DataGrid.OnGridLinesVisibilityPropertyChanged)));
        public static readonly DependencyProperty GroupColumnHeaderStyleProperty = DependencyProperty.Register("GroupColumnHeaderStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnGroupColumnHeaderStylePropertyChanged)));
        internal const string GroupingElementName = "Grouping";
        public static readonly DependencyProperty GroupingPanelBackgroundProperty = DependencyProperty.Register("GroupingPanelBackground", typeof(Brush), typeof(DataGrid), null);
        public static readonly DependencyProperty GroupingPanelForegroundProperty = DependencyProperty.Register("GroupingPanelForeground", typeof(Brush), typeof(DataGrid), null);
        public static readonly DependencyProperty GroupingPanelStyleProperty = DependencyProperty.Register("GroupingPanelStyle", typeof(Style), typeof(DataGrid), null);
        public static readonly DependencyProperty GroupRowHeaderStyleProperty = DependencyProperty.Register("GroupRowHeaderStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnGroupRowHeaderStylePropertyChanged)));
        public static readonly DependencyProperty GroupRowHeightProperty = DependencyProperty.Register("GroupRowHeight", typeof(DataGridLength), typeof(DataGrid), new PropertyMetadata(new DataGridLength(24.0), new PropertyChangedCallback(DataGrid.OnGroupRowHeightPropertyChanged)));
        public static readonly DependencyProperty GroupRowPositionProperty = DependencyProperty.Register("GroupRowPosition", typeof(DataGridGroupRowPosition), typeof(DataGrid), new PropertyMetadata(DataGridGroupRowPosition.AboveData, new PropertyChangedCallback(DataGrid.OnGroupRowPositionPropertyChanged)));
        public static readonly DependencyProperty GroupRowStyleProperty = DependencyProperty.Register("GroupRowStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnGroupRowStylePropertyChanged)));
        public static readonly DependencyProperty HeaderBackgroundProperty = DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnHeaderBackgroundPropertyChanged)));
        public static readonly DependencyProperty HeaderForegroundProperty = DependencyProperty.Register("HeaderForeground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnHeaderForegroundPropertyChanged)));
        public static readonly DependencyProperty HeadersVisibilityProperty = DependencyProperty.Register("HeadersVisibility", typeof(DataGridHeadersVisibility), typeof(DataGrid), new PropertyMetadata(DataGridHeadersVisibility.All, new PropertyChangedCallback(DataGrid.OnHeadersVisibilityPropertyChanged)));
        public static readonly DependencyProperty HorizontalGridLinesBrushProperty = DependencyProperty.Register("HorizontalGridLinesBrush", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnHorizontalGridLinesBrushPropertyChanged)));
        internal const string HorizontalScrollBarElementName = "HorizontalScrollBar";
        public static readonly DependencyProperty HorizontalScrollBarVisibilityProperty = DependencyProperty.Register("HorizontalScrollBarVisibility", typeof(ScrollBarVisibility), typeof(DataGrid), new PropertyMetadata(ScrollBarVisibility.Auto, new PropertyChangedCallback(DataGrid.OnHorizontalScrollBarVisibilityPropertyChanged)));
        public static readonly DependencyProperty IndentWidthProperty = DependencyProperty.Register("IndentWidth", typeof(double), typeof(DataGrid), new PropertyMetadata(22.0, new PropertyChangedCallback(DataGrid.OnIndentWidthPropertyChanged)));
        private bool isChangingCurrentCell;
        private bool isChangingSelection;
        public static readonly DependencyProperty IsLoadingProperty = DependencyProperty.Register("IsLoading", typeof(bool), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnIsLoadingPropertyChanged)));
        public static readonly DependencyProperty IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnIsMouseOverPropertyChanged)));
        public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(DataGrid), new PropertyMetadata(false, new PropertyChangedCallback(DataGrid.OnIsReadOnlyPropertyChanged)));
        public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnItemsSourcePropertyChanged)));
        public static readonly DependencyProperty LeadingColumnWidthProperty = DependencyProperty.Register("LeadingColumnWidth", typeof(DataGridLength), typeof(DataGrid), new PropertyMetadata(DataGridLength.Auto, new PropertyChangedCallback(DataGrid.OnLeadingColumnWidthPropertyChanged)));
        public static readonly DependencyProperty MaxColumnWidthProperty = DependencyProperty.Register("MaxColumnWidth", typeof(double), typeof(DataGrid), new PropertyMetadata((double)1.0 / (double)0.0, new PropertyChangedCallback(DataGrid.OnMaxColumnWidthPropertyChanged)));
        public static readonly DependencyProperty MaxRowHeightProperty = DependencyProperty.Register("MaxRowHeight", typeof(double), typeof(DataGrid), new PropertyMetadata((double)1.0 / (double)0.0, new PropertyChangedCallback(DataGrid.OnMaxRowHeightPropertyChanged)));
        public static readonly DependencyProperty MinColumnWidthProperty = DependencyProperty.Register("MinColumnWidth", typeof(double), typeof(DataGrid), new PropertyMetadata(15.0, new PropertyChangedCallback(DataGrid.OnMinColumnWidthPropertyChanged)));
        public static readonly DependencyProperty MinRowHeightProperty = DependencyProperty.Register("MinRowHeight", typeof(double), typeof(DataGrid), new PropertyMetadata(5.0, new PropertyChangedCallback(DataGrid.OnMinRowHeightPropertyChanged)));
        public static readonly DependencyProperty MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(DataGrid), null);
        public static readonly DependencyProperty NewRowHeaderStyleProperty = DependencyProperty.Register("NewRowHeaderStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnNewRowHeaderStylePropertyChanged)));
        public static readonly DependencyProperty NewRowStyleProperty = DependencyProperty.Register("NewRowStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnNewRowStylePropertyChanged)));
        public static readonly DependencyProperty NewRowVisibilityProperty = DependencyProperty.Register("NewRowVisibility", typeof(DataGridNewRowVisibility), typeof(DataGrid), new PropertyMetadata(DataGridNewRowVisibility.Bottom, new PropertyChangedCallback(DataGrid.OnNewRowVisibilityPropertyChanged)));
        internal const string PopupElementName = "Popup";
        public static readonly DependencyProperty PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(DataGrid), null);
        internal const string RootElementName = "Root";
        public static readonly DependencyProperty RowBackgroundProperty = DependencyProperty.Register("RowBackground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnRowBackgroundPropertyChanged)));
        public static readonly DependencyProperty RowDetailsTemplateProperty = DependencyProperty.Register("RowDetailsTemplate", typeof(DataTemplate), typeof(DataGrid), null);
        public static readonly DependencyProperty RowDetailsVisibilityModeProperty = DependencyProperty.Register("RowDetailsVisibilityMode", typeof(DataGridRowDetailsVisibilityMode), typeof(DataGrid), new PropertyMetadata(DataGridRowDetailsVisibilityMode.Collapsed));
        public static readonly DependencyProperty RowForegroundProperty = DependencyProperty.Register("RowForeground", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnRowForegroundPropertyChanged)));
        public static readonly DependencyProperty RowHeaderStyleProperty = DependencyProperty.Register("RowHeaderStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnRowHeaderStylePropertyChanged)));
        public static readonly DependencyProperty RowHeaderWidthProperty = DependencyProperty.Register("RowHeaderWidth", typeof(double), typeof(DataGrid), new PropertyMetadata(24.0, new PropertyChangedCallback(DataGrid.OnRowHeaderWidthPropertyChanged)));
        public static readonly DependencyProperty RowHeightProperty = DependencyProperty.Register("RowHeight", typeof(DataGridLength), typeof(DataGrid), new PropertyMetadata(new DataGridLength(25.0), new PropertyChangedCallback(DataGrid.OnRowHeightPropertyChanged)));
        internal const string RowsHeaderElementName = "RowsHeader";
        public static readonly DependencyProperty RowStyleProperty = DependencyProperty.Register("RowStyle", typeof(Style), typeof(DataGrid), null);
        public static readonly DependencyProperty ScrollBarStyleProperty = DependencyProperty.Register("ScrollBarStyle", typeof(Style), typeof(DataGrid), null);
        public static readonly DependencyProperty ScrollModeProperty = DependencyProperty.Register("ScrollMode", typeof(DataGridScrollMode), typeof(DataGrid), null);
        public static readonly DependencyProperty ScrollPreviewRowTemplateProperty = DependencyProperty.Register("ScrollPreviewRowTemplate", typeof(DataTemplate), typeof(DataGrid), null);
        public static readonly DependencyProperty SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(DataGrid), null);
        public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register("SelectedIndex", typeof(int), typeof(DataGrid), new PropertyMetadata(-1, new PropertyChangedCallback(DataGrid.OnSelectedIndexPropertyChanged)));
        public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", typeof(object), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnSelectedItemPropertyChanged)));
        public static readonly DependencyProperty SelectionModeProperty = DependencyProperty.Register("SelectionMode", typeof(DataGridSelectionMode), typeof(DataGrid), new PropertyMetadata(DataGridSelectionMode.MultiRow, new PropertyChangedCallback(DataGrid.OnSelectionModePropertyChanged)));
        public static readonly DependencyProperty ShowFluidMouseOverProperty = DependencyProperty.Register("ShowFluidMouseOver", typeof(bool), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnShowFluidMouseOverPropertyChanged)));
        public static readonly DependencyProperty ShowGroupingPanelProperty = DependencyProperty.Register("ShowGroupingPanel", typeof(bool), typeof(DataGrid), new PropertyMetadata(false, new PropertyChangedCallback(DataGrid.OnShowGroupingPanelPropertyChanged)));
        public static readonly DependencyProperty ShowValidationIndicatorsProperty = DependencyProperty.Register("ShowValidationIndicators", typeof(bool), typeof(DataGrid), new PropertyMetadata(true, new PropertyChangedCallback(DataGrid.OnShowValidationIndicatorsPropertyChanged)));
        public static readonly DependencyProperty ShowVerticalFreezingSeparatorProperty = DependencyProperty.Register("ShowVerticalFreezingSeparator", typeof(DataGridColumnFreezing), typeof(DataGrid), new PropertyMetadata(DataGridColumnFreezing.None, new PropertyChangedCallback(DataGrid.OnShowVerticalFreezingSeparatorPropertyChanged)));
        internal const string TopLeftCornerElementName = "TopLeftCorner";
        public static readonly DependencyProperty ValidationBackgroundProperty = DependencyProperty.Register("ValidationBackground", typeof(Brush), typeof(DataGrid), null);
        public static readonly DependencyProperty ValidationForegroundProperty = DependencyProperty.Register("ValidationForeground", typeof(Brush), typeof(DataGrid), null);
        public static readonly DependencyProperty VerticalFreezingSeparatorStyleProperty = DependencyProperty.Register("VerticalFreezingSeparatorStyle", typeof(Style), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnVerticalFreezingSeparatorStylePropertyChanged)));
        public static readonly DependencyProperty VerticalFreezingSeparatorWidthProperty = DependencyProperty.Register("VerticalFreezingSeparatorWidth", typeof(double), typeof(DataGrid), new PropertyMetadata(5.0, new PropertyChangedCallback(DataGrid.OnVerticalFreezingSeparatorWidthPropertyChanged)));
        public static readonly DependencyProperty VerticalGridLinesBrushProperty = DependencyProperty.Register("VerticalGridLinesBrush", typeof(Brush), typeof(DataGrid), new PropertyMetadata(new PropertyChangedCallback(DataGrid.OnVerticalGridLinesBrushPropertyChanged)));
        internal const string VerticalScrollBarElementName = "VerticalScrollBar";
        public static readonly DependencyProperty VerticalScrollBarVisibilityProperty = DependencyProperty.Register("VerticalScrollBarVisibility", typeof(ScrollBarVisibility), typeof(DataGrid), new PropertyMetadata(ScrollBarVisibility.Auto, new PropertyChangedCallback(DataGrid.OnVerticalScrollBarVisibilityPropertyChanged)));
        public static readonly DependencyProperty VerticalScrollStepProperty = DependencyProperty.Register("VerticalScrollStep", typeof(DataGridScrollStep), typeof(DataGrid), new PropertyMetadata(DataGridScrollStep.Discrete));

        // Events
        public event EventHandler AutoGeneratedColumns;

        public event EventHandler<DataGridAutoGeneratingColumnEventArgs> AutoGeneratingColumn;

        public event EventHandler<DataGridBeganEditEventArgs> BeganEdit;

        public event EventHandler<DataGridBeginningEditEventArgs> BeginningEdit;

        public event EventHandler<DataGridBeginningNewRowEventArgs> BeginningNewRow;

        public event EventHandler<DataGridEditingRowEventArgs> BeginningRowEdit;

        public event EventHandler<DataGridRowEventArgs> CanceledNewRow;

        public event EventHandler<DataGridRowEventArgs> CanceledRowEdit;

        public event EventHandler<DataGridEndingEditEventArgs> CancelingEdit;

        public event EventHandler<DataGridEndingNewRowEventArgs> CancelingNewRow;

        public event EventHandler<DataGridEditingRowEventArgs> CancelingRowEdit;

        public event EventHandler<DragCompletedEventArgs> ColumnHeaderDragCompleted;

        public event EventHandler<DragDeltaEventArgs> ColumnHeaderDragDelta;

        public event EventHandler<DragStartedEventArgs> ColumnHeaderDragStarted;

        public event EventHandler<DataGridColumnEventArgs> ColumnReordered;

        public event EventHandler<DataGridColumnReorderingEventArgs> ColumnReordering;

        public event EventHandler<DataGridColumnEventArgs> ColumnResized;

        public event EventHandler<DataGridColumnEventArgs> ColumnResizing;

        public event EventHandler<DataGridCellEventArgs> CommittedEdit;

        public event EventHandler<DataGridRowEventArgs> CommittedNewRow;

        public event EventHandler<DataGridRowEventArgs> CommittedRowEdit;

        public event EventHandler<DataGridEndingEditEventArgs> CommittingEdit;

        public event EventHandler<DataGridEndingNewRowEventArgs> CommittingNewRow;

        public event EventHandler<DataGridEditingRowEventArgs> CommittingRowEdit;

        public event EventHandler<DataGridCreatingRowEventArgs> CreatingRow;

        public event EventHandler<DataGridCellEventArgs> CurrentCellChanged;

        public event EventHandler<DataGridDeletingRowsEventArgs> DeletingRows;

        public event EventHandler<DataGridFilterChangedEventArgs> FilterChanged;

        public event EventHandler<DataGridFilterChangingEventArgs> FilterChanging;

        public event EventHandler<DataGridColumnEditableValueEventArgs<IDataGridFilter>> FilterLoading;

        public event EventHandler<DataGridColumnValueEventArgs<IDataGridFilter>> FilterOpened;

        public event EventHandler<PropertyChangedEventArgs<int>> FrozenBottomRowsCountChanged;

        public event EventHandler<PropertyChangedEventArgs<int>> FrozenColumnCountChanged;

        public event EventHandler<PropertyChangedEventArgs<int>> FrozenTopRowsCountChanged;

        public event EventHandler<DataGridGroupChangedEventArgs> GroupChanged;

        public event EventHandler<DataGridGroupChangingEventArgs> GroupChanging;

        public event EventHandler<PropertyChangedEventArgs<bool>> IsLoadingChanged;

        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;

        public event KeyEventHandler KeyDown;

        public event EventHandler<PropertyChangedEventArgs<DataGridLength>> LeadingColumnWidthChanged;

        public event EventHandler<DataGridCellEventArgs> LoadedCellPresenter;

        public event EventHandler<DataGridColumnEventArgs> LoadedColumnHeaderPresenter;

        public event EventHandler<DataGridRowDetailsEventArgs> LoadedRowDetailsPresenter;

        public event EventHandler<DataGridRowEventArgs> LoadedRowHeaderPresenter;

        public event EventHandler<DataGridRowEventArgs> LoadedRowPresenter;

        public event EventHandler<DataGridRowEventArgs> LoadingRow;

        public event EventHandler<DataGridMergingCellsEventArgs> MergingCells;

        public event PropertyChangedEventHandler PropertyChanged;

        public event EventHandler<DataGridRowEventArgs> RowDetailsVisibilityChanged;

        public event EventHandler<DataGridRowEventArgs> RowResized;

        public event EventHandler<DataGridRowEventArgs> RowResizing;

        public event EventHandler<DataGridRowsAddedEventArgs> RowsAdded;

        public event EventHandler<DataGridRowsDeletedEventArgs> RowsDeleted;

        public event EventHandler<DataGridSelectionChangedEventArgs> SelectionChanged;

        public event EventHandler<DataGridSelectionChangedEventArgs> SelectionChanging;

        public event EventHandler<DataGridSelectionDragEventArgs> SelectionDragCompleted;

        public event EventHandler<DataGridSelectionDragEventArgs> SelectionDragDelta;

        public event EventHandler<DataGridSelectionDragStartedEventArgs> SelectionDragStarted;

        public event EventHandler<DataGridSortChangedEventArgs> SortChanged;

        public event EventHandler<DataGridSortChangingEventArgs> SortChanging;

        public event EventHandler<DataGridCellEventArgs> UnloadedCellPresenter;

        public event EventHandler<DataGridColumnEventArgs> UnloadedColumnHeaderPresenter;

        public event EventHandler<DataGridRowDetailsEventArgs> UnloadedRowDetailsPresenter;

        public event EventHandler<DataGridRowEventArgs> UnloadedRowHeaderPresenter;

        public event EventHandler<DataGridRowEventArgs> UnloadedRowPresenter;

        public event EventHandler<DataGridRowEventArgs> UnloadingRow;

        // Methods
        public DataGrid()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this._throwLeadingColumnWidthChanged = true;
            this._throwFrozenColumnCountChanged = true;
            this._throwFrozenTopRowsCountChanged = true;
            this._throwFrozenBottomRowsCountChanged = true;
            this._throwIsLoadingChanged = true;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(DataGrid);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStateLoading(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
            this.SetCustomDefaultValues();
        }

        public bool BeginEdit()
        {
            return this.BeginEdit((RoutedEventArgs)null);
        }

        public bool BeginEdit(DataGridCell cell)
        {
            return ((this.View != null) && this.View.BeginCellEdit(cell));
        }

        public bool BeginEdit(RoutedEventArgs editingEventArgs)
        {
            return ((this.View != null) && this.View.BeginCellEdit(editingEventArgs));
        }

        public bool BeginEdit(int rowIndex, int columnIndex)
        {
            return ((this.View != null) && this.View.BeginCellEdit(rowIndex, columnIndex));
        }

        protected virtual void BeginInit()
        {
            this.Model.BeginInit();
        }

        public bool BeginNewRow()
        {
            return (((this.View != null) && this.View.IsLoaded) && this.View.BeginNewRow());
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        private void DataGrid_GotFocus(object sender, RoutedEventArgs e)
        {
            this.Focused = true;
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.ShowFocus();
            }
        }

        private void DataGrid_LostFocus(object sender, RoutedEventArgs e)
        {
            this.GetLogicalFocusedElement();
            this.Focused = false;
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.HideFocus();
            }
        }

        public bool CancelEdit()
        {
            return this.EndEdit(false, true);
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStateLoading(bool useTransitions)
        {
            if (!this.IsLoading)
            {
                VisualStateHelper.GoToState(this, "Ready", useTransitions);
            }
            if (this.IsLoading)
            {
                VisualStateHelper.GoToState(this, "Loading", useTransitions);
            }
        }

        public bool EndEdit()
        {
            return this.EndEdit(true, true);
        }

        public bool EndEdit(bool commitChanges)
        {
            return this.EndEdit(commitChanges, true);
        }

        public bool EndEdit(bool commitChanges, bool exitEditingMode)
        {
            return ((this.View != null) && this.View.EndEdit(commitChanges, exitEditingMode));
        }

        public bool EndEditRow(bool commitChanges)
        {
            return this.View.EndEditRow(commitChanges);
        }

        protected virtual void EndInit()
        {
            this.Model.EndInit();
        }

        public bool EndNewRow(bool commitChanges)
        {
            return (((this.View != null) && this.View.IsLoaded) && this.View.EndNewRow(commitChanges));
        }

        public void FilterBy(params DataGridColumnValue<DataGridFilterState>[] columns)
        {
            this.Model.FilterBy(columns);
        }

        public void FilterBy(params KeyValuePair<DataGridColumn, DataGridFilterState>[] columns)
        {
            this.Model.FilterBy((from pair in columns select new DataGridColumnValue<DataGridFilterState>(pair)).ToArray<DataGridColumnValue<DataGridFilterState>>());
        }

        public void FilterBy(DataGridColumn column, DataGridFilterState filterState)
        {
            this.Model.FilterBy(new DataGridColumnValue<DataGridFilterState>[] { new DataGridColumnValue<DataGridFilterState>(column, filterState) });
        }

        public void FilterBy(DataGridColumn column, DataGridFilterState filterState, bool preservePreviousFilters)
        {
            this.Model.FilterBy(column, filterState, preservePreviousFilters);
        }

        private void fluidOver_BeganEdit(object sender, DataGridBeganEditEventArgs e)
        {
            this._rectOverlay.Visibility = Visibility.Collapsed;
            this._isEditing = true;
        }

        private void fluidOver_CancelingEdit(object sender, DataGridEndingEditEventArgs e)
        {
            this._rectOverlay.Visibility = Visibility.Visible;
            this._isEditing = false;
        }

        private void fluidOver_CommittingEdit(object sender, DataGridEndingEditEventArgs e)
        {
            this._rectOverlay.Visibility = Visibility.Visible;
            this._isEditing = false;
        }

        private void fluidOver_MouseMove(object sender, MouseEventArgs e)
        {
            if (this._rectOverlay == null)
            {
                this._rectOverlay = new Rectangle();
                this._rectOverlay.Visibility = Visibility.Collapsed;
                this._rectOverlay.Fill = this.MouseOverBrush;
                this._rectOverlay.Opacity = 0.4;
                this._rectOverlay.IsHitTestVisible = false;
                Canvas canvas = new Canvas
                {
                    Children = { this._rectOverlay }
                };
                this._elementRoot.Children.Add(canvas);
            }
            if (this._isEditing)
            {
                this._rectOverlay.Visibility = Visibility.Collapsed;
            }
            else
            {
                Rect rect = this._elementBody.TransformToVisual(this._elementRoot).TransformBounds(new Rect(new Point(), this._elementBody.RenderSize));
                Point position = e.GetPosition(this._elementRoot);
                if (rect.Contains(position))
                {
                    this._rectOverlay.Visibility = Visibility.Visible;
                    double num = !this.RowHeight.IsAbsolute ? 24.0 : this.RowHeight.Value;
                    double num2 = position.Y - (num / 2.0);
                    num2 = Math.Max(rect.Top, num2);
                    num2 = Math.Min((rect.Top + rect.Height) - num, num2);
                    Canvas.SetLeft(this._rectOverlay, rect.Left);
                    Canvas.SetTop(this._rectOverlay, num2);
                    this._rectOverlay.Width = rect.Width;
                    this._rectOverlay.Height = num;
                }
                else
                {
                    this._rectOverlay.Visibility = Visibility.Collapsed;
                }
            }
        }

        public DataGridCell GetCell(int rowIndex, int columnIndex)
        {
            return this.Model.GetCell(rowIndex, columnIndex);
        }

        public DataGridCell GetCellFromFrameworkElement(FrameworkElement element)
        {
            return this.View.GetCellFromFrameworkElement(element);
        }

        public DataGridCell GetCellFromPoint(Point point)
        {
            return this.View.GetCellFromPoint(point, true);
        }

        public DataGridDetailsPresenter GetDetailFromPoint(Point point)
        {
            return this.View.GetDetailFromPoint(point);
        }

        public List<FrameworkElement> GetPageImages(ScaleMode scaleMode, Size pageSize, Thickness margin, int maxPages, out int verticalPageCount)
        {
            return this.GetPageImages(scaleMode, pageSize, margin, maxPages, true, out verticalPageCount);
        }

        public List<FrameworkElement> GetPageImages(ScaleMode scaleMode, Size pageSize, Thickness margin, int maxPages, bool showPageInfo, out int verticalPageCount)
        {
            PrintManager manager = new PrintManager(this)
            {
                ScaleMode = scaleMode,
                PrintableArea = pageSize,
                PageMargin = margin,
                MaxPages = maxPages,
                ShowPageInfo = showPageInfo
            };
            return manager.GetPageImages(out verticalPageCount);
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        public void GroupBy(params DataGridColumn[] columns)
        {
            List<DataGridColumnValue<DataGridSortDirection>> list = new List<DataGridColumnValue<DataGridSortDirection>>();
            foreach (DataGridColumn column in columns ?? new DataGridColumn[0])
            {
                list.Add(new DataGridColumnValue<DataGridSortDirection>(column, DataGridSortDirection.Ascending));
            }
            this.Model.GroupBy(list.ToArray());
        }

        public void GroupBy(params DataGridColumnValue<DataGridSortDirection>[] columns)
        {
            this.Model.GroupBy(columns);
        }

        public void GroupBy(params KeyValuePair<DataGridColumn, DataGridSortDirection>[] columns)
        {
            this.Model.GroupBy((from pair in columns select new DataGridColumnValue<DataGridSortDirection>(pair)).ToArray<DataGridColumnValue<DataGridSortDirection>>());
        }

        public void GroupBy(DataGridColumn column, DataGridSortDirection direction)
        {
            this.Model.GroupBy(new DataGridColumnValue<DataGridSortDirection>[] { new DataGridColumnValue<DataGridSortDirection>(column, direction) });
        }

        public void GroupBy(DataGridColumn column, DataGridSortDirection direction, bool preserveOtherColumnsGrouping)
        {
            this.Model.GroupBy(new DataGridColumnValue<DataGridSortDirection>[] { new DataGridColumnValue<DataGridSortDirection>(column, direction) }, preserveOtherColumnsGrouping);
        }

        private void InitializeInputHandlingStrategy()
        {
            base.KeyDown += delegate(object s, System.Windows.Input.KeyEventArgs e)
            {
                if (this.KeyDown != null)
                {
                    this.KeyDown(this, e);
                }
                if (!e.Handled)
                {
                    this.View.InputHandlingStrategy.HandleKeyDown(e);
                }
            };
            base.TextInput += delegate(object s, TextCompositionEventArgs e)
            {
                if (!string.IsNullOrEmpty(e.Text))
                {
                    this.BeginEdit(e);
                    e.Handled = true;
                }
            };
        }

        private void InitializeRootPart()
        {
            if (this._elementRoot.ColumnDefinitions.Count <= 1)
            {
                throw new InvalidOperationException("Root template part in DataGrid should have at least two columns.");
            }
            if (this._elementRoot.RowDefinitions.Count <= 1)
            {
                throw new InvalidOperationException("Root template part in DataGrid should have at least two rows.");
            }
            this.UpdateElementRoot();
        }

        public void MoveColumn(DataGridColumn column, int targetDisplayIndex)
        {
            if (this.Model != null)
            {
                this.Model.MoveColumn(column, targetDisplayIndex);
            }
        }

        private void OnAfterApplyTemplate()
        {
            this.InitializeInputHandlingStrategy();
            this.View.Load(this._elementBody, this._elementHorizontalScrollBar, this._elementVerticalScrollBar, this._elementGrouping, this._elementRowsHeader, this._elementColumnsHeader, this._elementTopLeftCorner, this._elementPopup);
        }

        private void OnAlternatingRowBackgroundChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateRowBackgroundAndForeground();
            }
        }

        private static void OnAlternatingRowBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnAlternatingRowBackgroundChanged(oldValue);
        }

        private void OnAlternatingRowForegroundChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateRowBackgroundAndForeground();
            }
        }

        private static void OnAlternatingRowForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnAlternatingRowForegroundChanged(oldValue);
        }

        public override void OnApplyTemplate()
        {
            this.OnBeforeApplyTemplate();
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementHorizontalScrollBar = this.GetTemplateChild<ScrollBar>("HorizontalScrollBar", true, ref errors);
            this._elementVerticalScrollBar = this.GetTemplateChild<ScrollBar>("VerticalScrollBar", true, ref errors);
            this._elementRowsHeader = this.GetTemplateChild<DataGridRowsHeaderPanel>("RowsHeader", false, ref errors);
            this._elementColumnsHeader = this.GetTemplateChild<DataGridColumnsHeaderPanel>("ColumnsHeader", false, ref errors);
            this._elementBody = this.GetTemplateChild<DataGridRowsPanel>("Body", true, ref errors);
            this._elementRoot = this.GetTemplateChild<Grid>("Root", true, ref errors);
            if (this._elementRoot != null)
            {
                this.InitializeRootPart();
            }
            this._elementGrouping = this.GetTemplateChild<DataGridGroupingPresenter>("Grouping", false, ref errors);
            this._elementTopLeftCorner = this.GetTemplateChild<Button>("TopLeftCorner", false, ref errors);
            this._elementPopup = this.GetTemplateChild<Popup>("Popup", true, ref errors);
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to DataGrid.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStateLoading(false);
                this.ChangeVisualStateCommon(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnAutoGenerateColumnsChanged(bool oldValue)
        {
            if (this.Model != null)
            {
                this.Model.AutoGenerateColumns();
            }
        }

        private static void OnAutoGenerateColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnAutoGenerateColumnsChanged(oldValue);
        }

        internal void OnAutoGeneratedColumns(EventArgs e)
        {
            EventHandler autoGeneratedColumns = this.AutoGeneratedColumns;
            if (autoGeneratedColumns != null)
            {
                try
                {
                    autoGeneratedColumns(this, e);
                }
                catch (Exception exception)
                {
                    if (!DesignerProperties.GetIsInDesignMode(this))
                    {
                        throw new InvalidOperationException("An exception has occurred in the Auto-Generated columns event handler", exception);
                    }
                }
            }
        }

        internal virtual void OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
        {
            EventHandler<DataGridAutoGeneratingColumnEventArgs> autoGeneratingColumn = this.AutoGeneratingColumn;
            if (autoGeneratingColumn != null)
            {
                autoGeneratingColumn(this, e);
            }
        }

        private void OnBeforeApplyTemplate()
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Unload();
            }
        }

        internal void OnBeganEdit(DataGridBeganEditEventArgs e)
        {
            EventHandler<DataGridBeganEditEventArgs> beganEdit = this.BeganEdit;
            if (beganEdit != null)
            {
                beganEdit(this, e);
            }
        }

        internal virtual void OnBeginningEdit(DataGridBeginningEditEventArgs e)
        {
            EventHandler<DataGridBeginningEditEventArgs> beginningEdit = this.BeginningEdit;
            if (beginningEdit != null)
            {
                beginningEdit(this, e);
            }
        }

        internal virtual void OnBeginningNewRow(DataGridBeginningNewRowEventArgs e)
        {
            EventHandler<DataGridBeginningNewRowEventArgs> beginningNewRow = this.BeginningNewRow;
            if (beginningNewRow != null)
            {
                beginningNewRow(this, e);
            }
        }

        internal virtual void OnBeginningRowEdit(DataGridEditingRowEventArgs e)
        {
            EventHandler<DataGridEditingRowEventArgs> beginningRowEdit = this.BeginningRowEdit;
            if (beginningRowEdit != null)
            {
                beginningRowEdit(this, e);
            }
        }

        internal virtual void OnCanceledNewRow(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> canceledNewRow = this.CanceledNewRow;
            if (canceledNewRow != null)
            {
                canceledNewRow(this, e);
            }
        }

        internal virtual void OnCanceledRowEdit(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> canceledRowEdit = this.CanceledRowEdit;
            if (canceledRowEdit != null)
            {
                canceledRowEdit(this, e);
            }
        }

        internal virtual void OnCancelingEdit(DataGridEndingEditEventArgs e)
        {
            EventHandler<DataGridEndingEditEventArgs> cancelingEdit = this.CancelingEdit;
            if (cancelingEdit != null)
            {
                cancelingEdit(this, e);
            }
        }

        internal virtual void OnCancelingNewRow(DataGridEndingNewRowEventArgs e)
        {
            EventHandler<DataGridEndingNewRowEventArgs> cancelingNewRow = this.CancelingNewRow;
            if (cancelingNewRow != null)
            {
                cancelingNewRow(this, e);
            }
        }

        internal virtual void OnCancelingRowEdit(DataGridEditingRowEventArgs e)
        {
            EventHandler<DataGridEditingRowEventArgs> cancelingRowEdit = this.CancelingRowEdit;
            if (cancelingRowEdit != null)
            {
                cancelingRowEdit(this, e);
            }
        }

        private void OnCanUserAddRowsChanged(bool oldValue)
        {
            if (this.Model != null)
            {
                this.Model.NewRowManager.UpdateNewRowVisibility();
            }
        }

        private static void OnCanUserAddRowsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserAddRowsChanged(oldValue);
        }

        private void OnCanUserEditRowsChanged(bool oldValue)
        {
            if (this.Model != null)
            {
                this.Model.NewRowManager.UpdateNewRowVisibility();
            }
        }

        private static void OnCanUserEditRowsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserEditRowsChanged(oldValue);
        }

        private void OnCanUserFilterChanged(bool oldValue)
        {
            if (this.Model != null)
            {
                this.Model.UpdateCanUserFilter();
            }
        }

        private static void OnCanUserFilterPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserFilterChanged(oldValue);
        }

        private void OnCanUserFreezeColumnsChanged(DataGridColumnFreezing oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.InvalidatePanelsMeasure();
            }
        }

        private static void OnCanUserFreezeColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridColumnFreezing oldValue = (DataGridColumnFreezing)e.OldValue;
            grid.OnCanUserFreezeColumnsChanged(oldValue);
        }

        private void OnCanUserGroupChanged(bool oldValue)
        {
            this.UpdateActualShowGroupingPanel();
        }

        private static void OnCanUserGroupPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserGroupChanged(oldValue);
        }

        private void OnCanUserReorderColumnsChanged(bool oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(true, true, true, true, true);
            }
            if (this.Model != null)
            {
                this.Model.UpdateCanUserReorderColumns();
            }
        }

        private static void OnCanUserReorderColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserReorderColumnsChanged(oldValue);
        }

        private void OnCanUserResizeColumnsChanged(bool oldValue)
        {
            if (this.Model != null)
            {
                this.Model.UpdateCanUserResizeColumns();
            }
        }

        private static void OnCanUserResizeColumnsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserResizeColumnsChanged(oldValue);
        }

        private void OnCanUserResizeRowsChanged(bool oldValue)
        {
            if (this.Model != null)
            {
                this.Model.UpdateCanUserResizeRows();
            }
        }

        private static void OnCanUserResizeRowsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserResizeRowsChanged(oldValue);
        }

        private void OnCanUserSelectByDraggingChanged(bool oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.InitializeDragHelper();
            }
        }

        private static void OnCanUserSelectByDraggingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserSelectByDraggingChanged(oldValue);
        }

        private void OnCanUserSortChanged(bool oldValue)
        {
        }

        private static void OnCanUserSortPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnCanUserSortChanged(oldValue);
        }

        private void OnCellStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnCellStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnCellStyleChanged(oldValue);
        }

        internal virtual void OnColumnHeaderDragCompleted(DragCompletedEventArgs e)
        {
            EventHandler<DragCompletedEventArgs> columnHeaderDragCompleted = this.ColumnHeaderDragCompleted;
            if (columnHeaderDragCompleted != null)
            {
                columnHeaderDragCompleted(this, e);
            }
        }

        internal virtual void OnColumnHeaderDragDelta(DragDeltaEventArgs e)
        {
            EventHandler<DragDeltaEventArgs> columnHeaderDragDelta = this.ColumnHeaderDragDelta;
            if (columnHeaderDragDelta != null)
            {
                columnHeaderDragDelta(this, e);
            }
        }

        internal virtual void OnColumnHeaderDragStarted(DragStartedEventArgs e)
        {
            EventHandler<DragStartedEventArgs> columnHeaderDragStarted = this.ColumnHeaderDragStarted;
            if (columnHeaderDragStarted != null)
            {
                columnHeaderDragStarted(this, e);
            }
        }

        private void OnColumnHeaderHeightChanged(double oldValue)
        {
            this.UpdateElementRoot();
        }

        private static void OnColumnHeaderHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnColumnHeaderHeightChanged(oldValue);
        }

        private void OnColumnHeaderStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnColumnHeaderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnColumnHeaderStyleChanged(oldValue);
        }

        internal virtual void OnColumnReordered(DataGridColumnEventArgs e)
        {
            EventHandler<DataGridColumnEventArgs> columnReordered = this.ColumnReordered;
            if (columnReordered != null)
            {
                columnReordered(this, e);
            }
        }

        internal virtual void OnColumnReordering(DataGridColumnReorderingEventArgs e)
        {
            EventHandler<DataGridColumnReorderingEventArgs> columnReordering = this.ColumnReordering;
            if (columnReordering != null)
            {
                columnReordering(this, e);
            }
        }

        internal virtual void OnColumnResized(DataGridColumnEventArgs e)
        {
            EventHandler<DataGridColumnEventArgs> columnResized = this.ColumnResized;
            if (columnResized != null)
            {
                columnResized(this, e);
            }
        }

        internal virtual void OnColumnResizing(DataGridColumnEventArgs e)
        {
            EventHandler<DataGridColumnEventArgs> columnResizing = this.ColumnResizing;
            if (columnResizing != null)
            {
                columnResizing(this, e);
            }
        }

        private void OnColumnWidthChanged(DataGridLength oldValue)
        {
            if (this.Model != null)
            {
                this.Model.UpdateColumnWidth(oldValue);
            }
        }

        private static void OnColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridLength oldValue = (DataGridLength)e.OldValue;
            grid.OnColumnWidthChanged(oldValue);
        }

        internal virtual void OnCommittedEdit(DataGridCellEventArgs e)
        {
            EventHandler<DataGridCellEventArgs> committedEdit = this.CommittedEdit;
            if (committedEdit != null)
            {
                committedEdit(this, e);
            }
        }

        internal virtual void OnCommittedNewRow(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> committedNewRow = this.CommittedNewRow;
            if (committedNewRow != null)
            {
                committedNewRow(this, e);
            }
        }

        internal virtual void OnCommittedRowEdit(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> committedRowEdit = this.CommittedRowEdit;
            if (committedRowEdit != null)
            {
                committedRowEdit(this, e);
            }
        }

        internal virtual void OnCommittingEdit(DataGridEndingEditEventArgs e)
        {
            EventHandler<DataGridEndingEditEventArgs> committingEdit = this.CommittingEdit;
            if (committingEdit != null)
            {
                committingEdit(this, e);
            }
        }

        internal virtual void OnCommittingNewRow(DataGridEndingNewRowEventArgs e)
        {
            EventHandler<DataGridEndingNewRowEventArgs> committingNewRow = this.CommittingNewRow;
            if (committingNewRow != null)
            {
                committingNewRow(this, e);
            }
        }

        internal virtual void OnCommittingRowEdit(DataGridEditingRowEventArgs e)
        {
            EventHandler<DataGridEditingRowEventArgs> committingRowEdit = this.CommittingRowEdit;
            if (committingRowEdit != null)
            {
                committingRowEdit(this, e);
            }
        }

        protected internal virtual void OnCopyPropertiesBeforeAddingItem(object editedItem, object collectionViewItem, PropertyInfo[] properties)
        {
            editedItem.SetProperties(collectionViewItem, properties);
        }

        internal virtual void OnCreatingRow(DataGridCreatingRowEventArgs e)
        {
            EventHandler<DataGridCreatingRowEventArgs> creatingRow = this.CreatingRow;
            if (creatingRow != null)
            {
                creatingRow(this, e);
            }
        }

        private void OnCurrentColumnChanged(DataGridColumn oldValue)
        {
            this.UpdateCurrentColumn();
        }

        private static void OnCurrentColumnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridColumn oldValue = (DataGridColumn)e.OldValue;
            grid.OnCurrentColumnChanged(oldValue);
        }

        private void OnCurrentRowChanged(DataGridRow oldValue)
        {
            this.UpdateCurrentRow();
        }

        internal virtual void OnCurrentRowOrColumnChanged(DataGridCellEventArgs e)
        {
            this.isChangingCurrentCell = true;
            this.CurrentColumn = this.Model.FocusAndEditingManager.CurrentColumn;
            this.CurrentRow = this.Model.FocusAndEditingManager.CurrentRow;
            this.isChangingCurrentCell = false;
            EventHandler<DataGridCellEventArgs> currentCellChanged = this.CurrentCellChanged;
            if (currentCellChanged != null)
            {
                currentCellChanged(this, e);
            }
        }

        private static void OnCurrentRowPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridRow oldValue = (DataGridRow)e.OldValue;
            grid.OnCurrentRowChanged(oldValue);
        }

        internal virtual void OnDeletingRows(DataGridDeletingRowsEventArgs e)
        {
            EventHandler<DataGridDeletingRowsEventArgs> deletingRows = this.DeletingRows;
            if (deletingRows != null)
            {
                deletingRows(this, e);
            }
        }

        private void OnDragOverColumnStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnDragOverColumnStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnDragOverColumnStyleChanged(oldValue);
        }

        private void OnDragSourceColumnStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnDragSourceColumnStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnDragSourceColumnStyleChanged(oldValue);
        }

        private void OnDropIndicatorStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnDropIndicatorStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnDropIndicatorStyleChanged(oldValue);
        }

        internal void OnFilterChanged(DataGridFilterChangedEventArgs e)
        {
            EventHandler<DataGridFilterChangedEventArgs> filterChanged = this.FilterChanged;
            if (filterChanged != null)
            {
                filterChanged(this, e);
            }
        }

        internal void OnFilterChanging(DataGridFilterChangingEventArgs e)
        {
            EventHandler<DataGridFilterChangingEventArgs> filterChanging = this.FilterChanging;
            if (filterChanging != null)
            {
                filterChanging(this, e);
            }
        }

        internal virtual void OnFilterLoading(DataGridColumnEditableValueEventArgs<IDataGridFilter> e)
        {
            EventHandler<DataGridColumnEditableValueEventArgs<IDataGridFilter>> filterLoading = this.FilterLoading;
            if (filterLoading != null)
            {
                filterLoading(this, e);
            }
        }

        internal virtual void OnFilterOpened(DataGridColumnValueEventArgs<IDataGridFilter> e)
        {
            EventHandler<DataGridColumnValueEventArgs<IDataGridFilter>> filterOpened = this.FilterOpened;
            if (filterOpened != null)
            {
                filterOpened(this, e);
            }
        }

        private void OnFilterStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnFilterStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnFilterStyleChanged(oldValue);
        }

        private void OnFocusStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnFocusStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnFocusStyleChanged(oldValue);
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as DataGrid).ChangeVisualStateCommon(true);
        }

        private static void OnFrozenBottomRowsCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid sender = d as DataGrid;
            if ((sender.FrozenBottomRowsCountChanged != null) && sender._throwFrozenBottomRowsCountChanged)
            {
                PropertyChangedEventArgs<int> args = new PropertyChangedEventArgs<int>
                {
                    OldValue = (int)e.OldValue,
                    NewValue = (int)e.NewValue
                };
                sender.FrozenBottomRowsCountChanged(sender, args);
            }
        }

        private static void OnFrozenColumnCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid sender = d as DataGrid;
            if ((sender.FrozenColumnCountChanged != null) && sender._throwFrozenColumnCountChanged)
            {
                PropertyChangedEventArgs<int> args = new PropertyChangedEventArgs<int>
                {
                    OldValue = (int)e.OldValue,
                    NewValue = (int)e.NewValue
                };
                sender.FrozenColumnCountChanged(sender, args);
            }
        }

        private static void OnFrozenTopRowsCountPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid sender = d as DataGrid;
            if ((sender.FrozenTopRowsCountChanged != null) && sender._throwFrozenTopRowsCountChanged)
            {
                PropertyChangedEventArgs<int> args = new PropertyChangedEventArgs<int>
                {
                    OldValue = (int)e.OldValue,
                    NewValue = (int)e.NewValue
                };
                sender.FrozenTopRowsCountChanged(sender, args);
            }
        }

        private void OnGridLinesVisibilityChanged(DataGridGridLinesVisibility oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateLines();
            }
        }

        private static void OnGridLinesVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridGridLinesVisibility oldValue = (DataGridGridLinesVisibility)e.OldValue;
            grid.OnGridLinesVisibilityChanged(oldValue);
        }

        internal void OnGroupChanged(DataGridGroupChangedEventArgs e)
        {
            EventHandler<DataGridGroupChangedEventArgs> groupChanged = this.GroupChanged;
            if (groupChanged != null)
            {
                groupChanged(this, e);
            }
        }

        internal void OnGroupChanging(DataGridGroupChangingEventArgs e)
        {
            EventHandler<DataGridGroupChangingEventArgs> groupChanging = this.GroupChanging;
            if (groupChanging != null)
            {
                groupChanging(this, e);
            }
        }

        private void OnGroupColumnHeaderStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnGroupColumnHeaderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnGroupColumnHeaderStyleChanged(oldValue);
        }

        private void OnGroupRowHeaderStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnGroupRowHeaderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnGroupRowHeaderStyleChanged(oldValue);
        }

        private void OnGroupRowHeightChanged(DataGridLength oldValue)
        {
            if (!this.RowHeight.IsAbsolute && !this.RowHeight.IsAuto)
            {
                this.GroupRowHeight = new DataGridLength(this.GroupRowHeight.Value);
            }
            else if (this.Model != null)
            {
                this.Model.UpdateGroupRowHeight(oldValue);
            }
        }

        private static void OnGroupRowHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridLength oldValue = (DataGridLength)e.OldValue;
            grid.OnGroupRowHeightChanged(oldValue);
        }

        private void OnGroupRowPositionChanged(DataGridGroupRowPosition oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(true, true, true, true, true);
            }
        }

        private static void OnGroupRowPositionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridGroupRowPosition oldValue = (DataGridGroupRowPosition)e.OldValue;
            grid.OnGroupRowPositionChanged(oldValue);
        }

        private void OnGroupRowStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnGroupRowStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnGroupRowStyleChanged(oldValue);
        }

        private void OnGroupStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private void OnHeaderBackgroundChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateRowBackgroundAndForeground();
            }
        }

        private static void OnHeaderBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnHeaderBackgroundChanged(oldValue);
        }

        private void OnHeaderForegroundChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateRowBackgroundAndForeground();
            }
        }

        private static void OnHeaderForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnHeaderForegroundChanged(oldValue);
        }

        private void OnHeadersVisibilityChanged(DataGridHeadersVisibility oldValue)
        {
            this.UpdateElementRoot();
        }

        private static void OnHeadersVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridHeadersVisibility oldValue = (DataGridHeadersVisibility)e.OldValue;
            grid.OnHeadersVisibilityChanged(oldValue);
        }

        private void OnHorizontalGridLinesBrushChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateLines();
            }
        }

        private static void OnHorizontalGridLinesBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnHorizontalGridLinesBrushChanged(oldValue);
        }

        private void OnHorizontalScrollBarVisibilityChanged(ScrollBarVisibility oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateHorizontalScrollBar();
            }
        }

        private static void OnHorizontalScrollBarVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            ScrollBarVisibility oldValue = (ScrollBarVisibility)e.OldValue;
            grid.OnHorizontalScrollBarVisibilityChanged(oldValue);
        }

        private void OnIndentWidthChanged(double oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateCellsAreaMargin();
            }
        }

        private static void OnIndentWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnIndentWidthChanged(oldValue);
        }

        private static void OnIsLoadingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid sender = d as DataGrid;
            if ((sender.IsLoadingChanged != null) && sender._throwIsLoadingChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsLoadingChanged(sender, args);
            }
            sender.ChangeVisualStateLoading(true);
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid sender = d as DataGrid;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private void OnIsReadOnlyChanged(bool oldValue)
        {
            if (this.IsReadOnly && !this.EndEdit(true, true))
            {
                this.EndEdit(false, true);
            }
            if (this.Model != null)
            {
                this.Model.NewRowManager.UpdateNewRowVisibility();
            }
        }

        private static void OnIsReadOnlyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnIsReadOnlyChanged(oldValue);
        }

        private void OnItemsSourceChanged(IEnumerable oldValue)
        {
            this.Model.OnItemsSourceChanged(this.ItemsSource);
        }

        private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            IEnumerable oldValue = (IEnumerable)e.OldValue;
            grid.OnItemsSourceChanged(oldValue);
        }

        private void OnLeadingColumnWidthChanged(DataGridLength oldValue)
        {
            if (!this.LeadingColumnWidth.IsAuto && !this.LeadingColumnWidth.IsAbsolute)
            {
                this.LeadingColumnWidth = oldValue;
            }
            else if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateCellsAreaMargin();
            }
        }

        private static void OnLeadingColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid sender = d as DataGrid;
            DataGridLength oldValue = (DataGridLength)e.OldValue;
            sender.OnLeadingColumnWidthChanged(oldValue);
            if ((sender.LeadingColumnWidthChanged != null) && sender._throwLeadingColumnWidthChanged)
            {
                PropertyChangedEventArgs<DataGridLength> args = new PropertyChangedEventArgs<DataGridLength>
                {
                    OldValue = (DataGridLength)e.OldValue,
                    NewValue = (DataGridLength)e.NewValue
                };
                sender.LeadingColumnWidthChanged(sender, args);
            }
        }

        internal void OnLoadedCellPresenter(DataGridCellEventArgs e)
        {
            EventHandler<DataGridCellEventArgs> loadedCellPresenter = this.LoadedCellPresenter;
            if (loadedCellPresenter != null)
            {
                loadedCellPresenter(this, e);
            }
        }

        internal void OnLoadedColumnHeaderPresenter(DataGridColumnEventArgs e)
        {
            EventHandler<DataGridColumnEventArgs> loadedColumnHeaderPresenter = this.LoadedColumnHeaderPresenter;
            if (loadedColumnHeaderPresenter != null)
            {
                loadedColumnHeaderPresenter(this, e);
            }
        }

        internal virtual void OnLoadedRow(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> loadingRow = this.LoadingRow;
            if (loadingRow != null)
            {
                loadingRow(this, e);
            }
        }

        internal virtual void OnLoadedRowDetailsPresenter(DataGridRowDetailsEventArgs e)
        {
            EventHandler<DataGridRowDetailsEventArgs> loadedRowDetailsPresenter = this.LoadedRowDetailsPresenter;
            if (loadedRowDetailsPresenter != null)
            {
                loadedRowDetailsPresenter(this, e);
            }
        }

        internal void OnLoadedRowHeaderPresenter(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> loadedRowHeaderPresenter = this.LoadedRowHeaderPresenter;
            if (loadedRowHeaderPresenter != null)
            {
                loadedRowHeaderPresenter(this, e);
            }
        }

        internal void OnLoadedRowPresenter(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> loadedRowPresenter = this.LoadedRowPresenter;
            if (loadedRowPresenter != null)
            {
                loadedRowPresenter(this, e);
            }
        }

        private void OnMaxColumnWidthChanged(double oldValue)
        {
            if (double.IsNaN(this.MaxColumnWidth) || (this.MaxColumnWidth < 0.0))
            {
                this.MaxColumnWidth = double.PositiveInfinity;
            }
            if (this.Model != null)
            {
                this.Model.UpdateMaxColumnWidth(oldValue);
            }
        }

        private static void OnMaxColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnMaxColumnWidthChanged(oldValue);
        }

        private void OnMaxRowHeightChanged(double oldValue)
        {
            if (double.IsNaN(this.MinRowHeight) || (this.MinRowHeight < 0.0))
            {
                this.MinRowHeight = double.PositiveInfinity;
            }
            else if (this.Model != null)
            {
                this.Model.UpdateMaxRowHeight();
            }
        }

        private static void OnMaxRowHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnMaxRowHeightChanged(oldValue);
        }

        private void OnMinColumnWidthChanged(double oldValue)
        {
            if ((double.IsInfinity(this.MinColumnWidth) || double.IsNaN(this.MinColumnWidth)) || (this.MinColumnWidth < 0.0))
            {
                this.MinColumnWidth = 0.0;
            }
            if (this.Model != null)
            {
                this.Model.UpdateMinColumnWidth(oldValue);
            }
        }

        private static void OnMinColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnMinColumnWidthChanged(oldValue);
        }

        private void OnMinRowHeightChanged(double oldValue)
        {
            if ((double.IsInfinity(this.MinRowHeight) || double.IsNaN(this.MinRowHeight)) || (this.MinRowHeight < 0.0))
            {
                this.MinRowHeight = 0.0;
            }
            else if (this.Model != null)
            {
                this.Model.UpdateMinRowHeight();
            }
        }

        private static void OnMinRowHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnMinRowHeightChanged(oldValue);
        }

        private void OnNewRowHeaderStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnNewRowHeaderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnNewRowHeaderStyleChanged(oldValue);
        }

        private void OnNewRowStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnNewRowStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnNewRowStyleChanged(oldValue);
        }

        private void OnNewRowVisibilityChanged(DataGridNewRowVisibility oldValue)
        {
            if (this.Model != null)
            {
                this.Model.NewRowManager.UpdateNewRowVisibility();
            }
        }

        private static void OnNewRowVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridNewRowVisibility oldValue = (DataGridNewRowVisibility)e.OldValue;
            grid.OnNewRowVisibilityChanged(oldValue);
        }

        private void OnRowBackgroundChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateRowBackgroundAndForeground();
            }
        }

        private static void OnRowBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnRowBackgroundChanged(oldValue);
        }

        internal virtual void OnRowDetailsVisibilityChanged(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> rowDetailsVisibilityChanged = this.RowDetailsVisibilityChanged;
            if (rowDetailsVisibilityChanged != null)
            {
                rowDetailsVisibilityChanged(this, e);
            }
        }

        private void OnRowForegroundChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateRowBackgroundAndForeground();
            }
        }

        private static void OnRowForegroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnRowForegroundChanged(oldValue);
        }

        private void OnRowHeaderStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnRowHeaderStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnRowHeaderStyleChanged(oldValue);
        }

        private void OnRowHeaderWidthChanged(double oldValue)
        {
            this.UpdateElementRoot();
        }

        private static void OnRowHeaderWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnRowHeaderWidthChanged(oldValue);
        }

        private void OnRowHeightChanged(DataGridLength oldValue)
        {
            if (!this.RowHeight.IsAbsolute && !this.RowHeight.IsAuto)
            {
                this.RowHeight = new DataGridLength(this.RowHeight.Value);
            }
            else if (this.Model != null)
            {
                this.Model.UpdateRowHeight(oldValue);
            }
        }

        private static void OnRowHeightPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridLength oldValue = (DataGridLength)e.OldValue;
            grid.OnRowHeightChanged(oldValue);
        }

        internal virtual void OnRowResized(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> rowResized = this.RowResized;
            if (rowResized != null)
            {
                rowResized(this, e);
            }
        }

        internal virtual void OnRowResizing(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> rowResizing = this.RowResizing;
            if (rowResizing != null)
            {
                rowResizing(this, e);
            }
        }

        internal virtual void OnRowsAdded(DataGridRowsAddedEventArgs e)
        {
            EventHandler<DataGridRowsAddedEventArgs> rowsAdded = this.RowsAdded;
            if (rowsAdded != null)
            {
                rowsAdded(this, e);
            }
        }

        internal virtual void OnRowsDeleted(DataGridRowsDeletedEventArgs e)
        {
            EventHandler<DataGridRowsDeletedEventArgs> rowsDeleted = this.RowsDeleted;
            if (rowsDeleted != null)
            {
                rowsDeleted(this, e);
            }
        }

        private void OnSelectedIndexChanged(int oldValue)
        {
            this.UpdateSelectedIndex(this.SelectedIndex);
        }

        private static void OnSelectedIndexPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            int oldValue = (int)e.OldValue;
            grid.OnSelectedIndexChanged(oldValue);
        }

        private void OnSelectedItemChanged(object oldValue)
        {
            this.UpdateSelectedItem();
        }

        private static void OnSelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            object oldValue = e.OldValue;
            grid.OnSelectedItemChanged(oldValue);
        }

        private void OnSelectedItemsChanged(IList<object> oldValue)
        {
        }

        internal virtual void OnSelectionChanged(DataGridSelectionChangedEventArgs e)
        {
            this.isChangingSelection = true;
            this.SelectedIndex = (this.Model.SelectionManager.SelectedRow == null) ? -1 : this.Model.SelectionManager.SelectedRow.Index;
            this.SelectedItem = (this.Model.SelectionManager.SelectedRow == null) ? null : this.Model.SelectionManager.SelectedRow.DataItem;
            this.isChangingSelection = false;
            this.RaisePropertyChanged("SelectedItems");
            EventHandler<DataGridSelectionChangedEventArgs> selectionChanged = this.SelectionChanged;
            if (selectionChanged != null)
            {
                selectionChanged(this, e);
            }
        }

        internal virtual void OnSelectionChanging(DataGridSelectionChangedEventArgs e)
        {
            EventHandler<DataGridSelectionChangedEventArgs> selectionChanging = this.SelectionChanging;
            if (selectionChanging != null)
            {
                selectionChanging(this, e);
            }
        }

        internal virtual void OnSelectionDragCompleted(DataGridSelectionDragEventArgs e)
        {
            EventHandler<DataGridSelectionDragEventArgs> selectionDragCompleted = this.SelectionDragCompleted;
            if (selectionDragCompleted != null)
            {
                selectionDragCompleted(this, e);
            }
        }

        internal virtual void OnSelectionDragDelta(DataGridSelectionDragEventArgs e)
        {
            EventHandler<DataGridSelectionDragEventArgs> selectionDragDelta = this.SelectionDragDelta;
            if (selectionDragDelta != null)
            {
                selectionDragDelta(this, e);
            }
        }

        internal virtual void OnSelectionDragStarted(DataGridSelectionDragStartedEventArgs e)
        {
            EventHandler<DataGridSelectionDragStartedEventArgs> selectionDragStarted = this.SelectionDragStarted;
            if (selectionDragStarted != null)
            {
                selectionDragStarted(this, e);
            }
        }

        private void OnSelectionModeChanged(DataGridSelectionMode oldValue)
        {
            if (this.Model != null)
            {
                this.Model.SelectionManager.Selection.Mode = this.SelectionMode;
            }
        }

        private static void OnSelectionModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridSelectionMode oldValue = (DataGridSelectionMode)e.OldValue;
            grid.OnSelectionModeChanged(oldValue);
        }

        private void OnShowFluidMouseOverChanged(bool oldValue)
        {
            RoutedEventHandler handler = null;
            if (this.ShowFluidMouseOver)
            {
                if (!this._isLoaded)
                {
                    if (handler == null)
                    {
                        handler = (s, e) => this.OnShowFluidMouseOverChanged(false);
                    }
                    base.Loaded += handler;
                }
                else
                {
                    base.MouseMove += new MouseEventHandler(this.fluidOver_MouseMove);
                    this.BeganEdit += new EventHandler<DataGridBeganEditEventArgs>(this.fluidOver_BeganEdit);
                    this.CancelingEdit += new EventHandler<DataGridEndingEditEventArgs>(this.fluidOver_CancelingEdit);
                    this.CommittingEdit += new EventHandler<DataGridEndingEditEventArgs>(this.fluidOver_CommittingEdit);
                }
            }
            else
            {
                base.MouseMove -= new MouseEventHandler(this.fluidOver_MouseMove);
                this.BeganEdit -= new EventHandler<DataGridBeganEditEventArgs>(this.fluidOver_BeganEdit);
                this.CancelingEdit -= new EventHandler<DataGridEndingEditEventArgs>(this.fluidOver_CancelingEdit);
                this.CommittingEdit -= new EventHandler<DataGridEndingEditEventArgs>(this.fluidOver_CommittingEdit);
            }
        }

        private static void OnShowFluidMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnShowFluidMouseOverChanged(oldValue);
        }

        private void OnShowGroupingPanelChanged(bool oldValue)
        {
            this.UpdateActualShowGroupingPanel();
        }

        private static void OnShowGroupingPanelPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnShowGroupingPanelChanged(oldValue);
        }

        private void OnShowValidationIndicatorsChanged(bool oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateValidationState();
            }
        }

        private static void OnShowValidationIndicatorsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            bool oldValue = (bool)e.OldValue;
            grid.OnShowValidationIndicatorsChanged(oldValue);
        }

        private void OnShowVerticalFreezingSeparatorChanged(DataGridColumnFreezing oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.InvalidatePanelsMeasure();
            }
        }

        private static void OnShowVerticalFreezingSeparatorPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            DataGridColumnFreezing oldValue = (DataGridColumnFreezing)e.OldValue;
            grid.OnShowVerticalFreezingSeparatorChanged(oldValue);
        }

        internal void OnSortChanged(DataGridSortChangedEventArgs e)
        {
            EventHandler<DataGridSortChangedEventArgs> sortChanged = this.SortChanged;
            if (sortChanged != null)
            {
                sortChanged(this, e);
            }
        }

        internal void OnSortChanging(DataGridSortChangingEventArgs e)
        {
            EventHandler<DataGridSortChangingEventArgs> sortChanging = this.SortChanging;
            if (sortChanging != null)
            {
                sortChanging(this, e);
            }
        }

        internal virtual void OnUnloadedCellPresenter(DataGridCellEventArgs e)
        {
            EventHandler<DataGridCellEventArgs> unloadedCellPresenter = this.UnloadedCellPresenter;
            if (unloadedCellPresenter != null)
            {
                unloadedCellPresenter(this, e);
            }
        }

        internal virtual void OnUnloadedColumnHeaderPresenter(DataGridColumnEventArgs e)
        {
            EventHandler<DataGridColumnEventArgs> unloadedColumnHeaderPresenter = this.UnloadedColumnHeaderPresenter;
            if (unloadedColumnHeaderPresenter != null)
            {
                unloadedColumnHeaderPresenter(this, e);
            }
        }

        internal virtual void OnUnloadedRowDetailsPresenter(DataGridRowDetailsEventArgs e)
        {
            EventHandler<DataGridRowDetailsEventArgs> unloadedRowDetailsPresenter = this.UnloadedRowDetailsPresenter;
            if (unloadedRowDetailsPresenter != null)
            {
                unloadedRowDetailsPresenter(this, e);
            }
        }

        internal virtual void OnUnloadedRowHeaderPresenter(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> unloadedRowHeaderPresenter = this.UnloadedRowHeaderPresenter;
            if (unloadedRowHeaderPresenter != null)
            {
                unloadedRowHeaderPresenter(this, e);
            }
        }

        internal virtual void OnUnloadedRowPresenter(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> unloadedRowPresenter = this.UnloadedRowPresenter;
            if (unloadedRowPresenter != null)
            {
                unloadedRowPresenter(this, e);
            }
        }

        internal virtual void OnUnloadingRow(DataGridRowEventArgs e)
        {
            EventHandler<DataGridRowEventArgs> unloadingRow = this.UnloadingRow;
            if (unloadingRow != null)
            {
                unloadingRow(this, e);
            }
        }

        private void OnVerticalFreezingSeparatorStyleChanged(Style oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(false, true, true, true, true);
            }
        }

        private static void OnVerticalFreezingSeparatorStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Style oldValue = (Style)e.OldValue;
            grid.OnVerticalFreezingSeparatorStyleChanged(oldValue);
        }

        private void OnVerticalFreezingSeparatorWidthChanged(double oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.Refresh(true, true, true, true, true);
            }
        }

        private static void OnVerticalFreezingSeparatorWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            double oldValue = (double)e.OldValue;
            grid.OnVerticalFreezingSeparatorWidthChanged(oldValue);
        }

        private void OnVerticalGridLinesBrushChanged(Brush oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateLines();
            }
        }

        private static void OnVerticalGridLinesBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            Brush oldValue = (Brush)e.OldValue;
            grid.OnVerticalGridLinesBrushChanged(oldValue);
        }

        private void OnVerticalScrollBarVisibilityChanged(ScrollBarVisibility oldValue)
        {
            if ((this.View != null) && this.View.IsLoaded)
            {
                this.View.UpdateVerticalScrollBar();
            }
        }

        private static void OnVerticalScrollBarVisibilityPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            DataGrid grid = d as DataGrid;
            ScrollBarVisibility oldValue = (ScrollBarVisibility)e.OldValue;
            grid.OnVerticalScrollBarVisibilityChanged(oldValue);
        }

        public bool PageDown(bool changeSelection)
        {
            return ((this.View != null) && this.View.PageDown(changeSelection));
        }

        public bool PageUp(bool changeSelection)
        {
            return ((this.View != null) && this.View.PageUp(changeSelection));
        }

        public void Print(string documentName)
        {
            new PrintManager(this).Print(documentName);
        }

        public void Print(string documentName, PrinterFallbackSettings fallBackSettings, bool useDefaultPrinter)
        {
            new PrintManager(this) { FallBackSettings = fallBackSettings, UseDefaultPrinter = useDefaultPrinter }.Print(documentName);
        }

        public void Print(string documentName, ScaleMode scaleMode, Thickness margin, int maxPages)
        {
            new PrintManager(this) { ScaleMode = scaleMode, PageMargin = margin, MaxPages = maxPages }.Print(documentName);
        }

        public void Print(string documentName, ScaleMode scaleMode, Thickness margin, int maxPages, PrinterFallbackSettings fallBackSettings, bool useDefaultPrinter)
        {
            new PrintManager(this) { ScaleMode = scaleMode, PageMargin = margin, MaxPages = maxPages, FallBackSettings = fallBackSettings, UseDefaultPrinter = useDefaultPrinter }.Print(documentName);
        }

        protected void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public void Refresh(bool recycle = false, bool refreshRows = true, bool refreshCells = true, bool refreshColumnHeaders = true, bool refreshRowHeaders = true)
        {
            if (this.View != null)
            {
                this.View.Refresh(recycle, refreshRows, refreshCells, refreshColumnHeaders, refreshRowHeaders);
            }
        }

        public bool Reload(bool createColumns)
        {
            if (this.Model != null)
            {
                this.Model.Reload(createColumns);
            }
            return true;
        }

        public bool RemoveRow(int rowIndex)
        {
            return (((this.View != null) && this.View.IsLoaded) && this.View.RemoveRows(new int[] { rowIndex }));
        }

        public bool RemoveRows(DataGridRow[] removedRows)
        {
            return (((this.View != null) && this.View.IsLoaded) && this.View.RemoveRows(removedRows));
        }

        public bool RemoveRows(int[] rowIndexes)
        {
            return (((this.View != null) && this.View.IsLoaded) && this.View.RemoveRows(rowIndexes));
        }

        public void ScrollIntoView()
        {
            if (this.View != null)
            {
                this.View.ScrollIntoView();
            }
        }

        public void ScrollIntoView(FrameworkElement element)
        {
            if (this.View != null)
            {
                this.View.ScrollIntoView(element);
            }
        }

        public void ScrollIntoView(int rowIndex, int columnIndex)
        {
            if (this.View != null)
            {
                this.View.ScrollIntoView(rowIndex, columnIndex);
            }
        }

        public void ScrollIntoView(object item, DataGridColumn column)
        {
            if (this.View != null)
            {
                this.View.ScrollIntoView(item, column);
            }
        }

        private void SetCustomDefaultValues()
        {
            this.Focused = false;
            base.GotFocus += new RoutedEventHandler(this.DataGrid_GotFocus);
            base.LostFocus += new RoutedEventHandler(this.DataGrid_LostFocus);
            this.Model = new DataGridModel(this, this.SelectionMode);
            this.View = new DataGridView(this, this.Model);
            base.MouseLeftButtonDown += (s, e) => e.Handled = true;
        }

        public void SortBy(params DataGridColumn[] columns)
        {
            List<DataGridColumnValue<DataGridSortDirection>> list = new List<DataGridColumnValue<DataGridSortDirection>>();
            foreach (DataGridColumn column in columns ?? new DataGridColumn[0])
            {
                list.Add(new DataGridColumnValue<DataGridSortDirection>(column, DataGridSortDirection.Ascending));
            }
            this.Model.SortBy(list.ToArray());
        }

        public void SortBy(params DataGridColumnValue<DataGridSortDirection>[] columns)
        {
            if (this.Model != null)
            {
                this.Model.SortBy(columns);
            }
        }

        public void SortBy(params KeyValuePair<DataGridColumn, DataGridSortDirection>[] columns)
        {
            if (this.Model != null)
            {
                this.Model.SortBy((from pair in columns select new DataGridColumnValue<DataGridSortDirection>(pair)).ToArray<DataGridColumnValue<DataGridSortDirection>>());
            }
        }

        public void SortBy(DataGridColumn column, DataGridSortDirection direction)
        {
            this.Model.SortBy(new DataGridColumnValue<DataGridSortDirection>[] { new DataGridColumnValue<DataGridSortDirection>(new KeyValuePair<DataGridColumn, DataGridSortDirection>(column, direction)) });
        }

        public void SortBy(DataGridColumn column, DataGridSortDirection direction, bool preservePreviousSorting)
        {
            this.Model.SortBy(column, direction, preservePreviousSorting);
        }

        void ISupportInitialize.BeginInit()
        {
            this.BeginInit();
        }

        void ISupportInitialize.EndInit()
        {
            this.EndInit();
        }

        private void UpdateActualShowGroupingPanel()
        {
            base.SetValue(ActualShowGroupingPanelProperty, this.CanUserGroup ? ((object)1) : ((object)this.ShowGroupingPanel));
        }

        private void UpdateCurrentColumn()
        {
            if ((this.Model != null) && !this.isChangingCurrentCell)
            {
                if (this.CurrentColumn == null)
                {
                    this.Model.ClearCurrentColumn(true);
                }
                else
                {
                    this.Model.SetCurrentColumn(this.CurrentColumn, true);
                }
            }
        }

        private void UpdateCurrentRow()
        {
            if ((this.Model != null) && !this.isChangingCurrentCell)
            {
                if (this.CurrentRow == null)
                {
                    this.Model.ClearCurrentRow(true);
                }
                else
                {
                    this.Model.SetCurrentRow(this.CurrentRow, true);
                }
            }
        }

        private void UpdateElementRoot()
        {
            if (this._elementRoot != null)
            {
                if (this._elementRoot.ColumnDefinitions.Count > 0)
                {
                    this._elementRoot.ColumnDefinitions[0].Width = new GridLength(((this.HeadersVisibility & DataGridHeadersVisibility.Row) == DataGridHeadersVisibility.Row) ? this.RowHeaderWidth : 0.0);
                }
                if (this._elementRoot.RowDefinitions.Count > 0)
                {
                    this._elementRoot.RowDefinitions[0].Height = new GridLength(((this.HeadersVisibility & DataGridHeadersVisibility.Column) == DataGridHeadersVisibility.Column) ? this.ColumnHeaderHeight : 0.0);
                }
            }
        }

        internal void UpdateSelectedIndex(int selectedIndex)
        {
            if (((this.Model != null) && !this.isChangingSelection) && this.SelectionMode.IsRowSelectionMode())
            {
                if ((selectedIndex >= 0) && (selectedIndex < this.Model.Rows.Count))
                {
                    this.Model.SelectionManager.Select(this.Model.Rows[selectedIndex], false, false);
                }
                else if (selectedIndex == -1)
                {
                    this.Model.SelectionManager.Clear();
                }
            }
        }

        internal bool UpdateSelectedItem()
        {
            if ((this.Model != null) && !this.isChangingSelection)
            {
                if (this.SelectedItem != null)
                {
                    DataGridRow row = this.Model.Rows[this.SelectedItem];
                    if (row != null)
                    {
                        this.Model.SelectionManager.Select(row, false, false);
                        return true;
                    }
                }
                else
                {
                    this.Model.SelectionManager.Clear();
                }
            }
            return false;
        }

        // Properties
        internal bool ActualShowGroupingPanel
        {
            get
            {
                return (bool)base.GetValue(ActualShowGroupingPanelProperty);
            }
            set
            {
                base.SetValue(ActualShowGroupingPanelProperty, value);
            }
        }

        public Brush AlternatingRowBackground
        {
            get
            {
                return (Brush)base.GetValue(AlternatingRowBackgroundProperty);
            }
            set
            {
                base.SetValue(AlternatingRowBackgroundProperty, value);
            }
        }

        public Brush AlternatingRowForeground
        {
            get
            {
                return (Brush)base.GetValue(AlternatingRowForegroundProperty);
            }
            set
            {
                base.SetValue(AlternatingRowForegroundProperty, value);
            }
        }

        public bool AutoGenerateColumns
        {
            get
            {
                return (bool)base.GetValue(AutoGenerateColumnsProperty);
            }
            set
            {
                base.SetValue(AutoGenerateColumnsProperty, value);
            }
        }

        public Rect BodyRect
        {
            get
            {
                return (Rect)base.GetValue(BodyRectProperty);
            }
            set
            {
                base.SetValue(BodyRectProperty, value);
            }
        }

        public Collection<DataGridRow> BottomRows
        {
            get
            {
                return this.Rows.BottomRows;
            }
        }

        public bool CanUserAddRows
        {
            get
            {
                return (bool)base.GetValue(CanUserAddRowsProperty);
            }
            set
            {
                base.SetValue(CanUserAddRowsProperty, value);
            }
        }

        public bool CanUserEditRows
        {
            get
            {
                return (bool)base.GetValue(CanUserEditRowsProperty);
            }
            set
            {
                base.SetValue(CanUserEditRowsProperty, value);
            }
        }

        public bool CanUserFilter
        {
            get
            {
                return (bool)base.GetValue(CanUserFilterProperty);
            }
            set
            {
                base.SetValue(CanUserFilterProperty, value);
            }
        }

        public DataGridColumnFreezing CanUserFreezeColumns
        {
            get
            {
                return (DataGridColumnFreezing)base.GetValue(CanUserFreezeColumnsProperty);
            }
            set
            {
                base.SetValue(CanUserFreezeColumnsProperty, value);
            }
        }

        public bool CanUserGroup
        {
            get
            {
                return (bool)base.GetValue(CanUserGroupProperty);
            }
            set
            {
                base.SetValue(CanUserGroupProperty, value);
            }
        }

        public bool CanUserRemoveRows
        {
            get
            {
                return (bool)base.GetValue(CanUserRemoveRowsProperty);
            }
            set
            {
                base.SetValue(CanUserRemoveRowsProperty, value);
            }
        }

        public bool CanUserReorderColumns
        {
            get
            {
                return (bool)base.GetValue(CanUserReorderColumnsProperty);
            }
            set
            {
                base.SetValue(CanUserReorderColumnsProperty, value);
            }
        }

        public bool CanUserResizeColumns
        {
            get
            {
                return (bool)base.GetValue(CanUserResizeColumnsProperty);
            }
            set
            {
                base.SetValue(CanUserResizeColumnsProperty, value);
            }
        }

        public bool CanUserResizeRows
        {
            get
            {
                return (bool)base.GetValue(CanUserResizeRowsProperty);
            }
            set
            {
                base.SetValue(CanUserResizeRowsProperty, value);
            }
        }

        public bool CanUserSelectByDragging
        {
            get
            {
                return (bool)base.GetValue(CanUserSelectByDraggingProperty);
            }
            set
            {
                base.SetValue(CanUserSelectByDraggingProperty, value);
            }
        }

        public bool CanUserSort
        {
            get
            {
                return (bool)base.GetValue(CanUserSortProperty);
            }
            set
            {
                base.SetValue(CanUserSortProperty, value);
            }
        }

        public bool CanUserToggleDetails
        {
            get
            {
                return (bool)base.GetValue(CanUserToggleDetailsProperty);
            }
            set
            {
                base.SetValue(CanUserToggleDetailsProperty, value);
            }
        }

        public Style CellStyle
        {
            get
            {
                return (Style)base.GetValue(CellStyleProperty);
            }
            set
            {
                base.SetValue(CellStyleProperty, value);
            }
        }

        public DataGridClipboardMode ClipboardCopyMode
        {
            get
            {
                return (DataGridClipboardMode)base.GetValue(ClipboardCopyModeProperty);
            }
            set
            {
                base.SetValue(ClipboardCopyModeProperty, value);
            }
        }

        public DataGridClipboardMode ClipboardPasteMode
        {
            get
            {
                return (DataGridClipboardMode)base.GetValue(ClipboardPasteModeProperty);
            }
            set
            {
                base.SetValue(ClipboardPasteModeProperty, value);
            }
        }

        public DataGridColumnHeaderClickAction ColumnHeaderClickAction
        {
            get
            {
                return (DataGridColumnHeaderClickAction)base.GetValue(ColumnHeaderClickActionProperty);
            }
            set
            {
                base.SetValue(ColumnHeaderClickActionProperty, value);
            }
        }

        public double ColumnHeaderHeight
        {
            get
            {
                return (double)base.GetValue(ColumnHeaderHeightProperty);
            }
            set
            {
                base.SetValue(ColumnHeaderHeightProperty, value);
            }
        }

        public DataGridOptionsVisibility ColumnHeaderOptionsVisibility
        {
            get
            {
                return (DataGridOptionsVisibility)base.GetValue(ColumnHeaderOptionsVisibilityProperty);
            }
            set
            {
                base.SetValue(ColumnHeaderOptionsVisibilityProperty, value);
            }
        }

        public Style ColumnHeaderStyle
        {
            get
            {
                return (Style)base.GetValue(ColumnHeaderStyleProperty);
            }
            set
            {
                base.SetValue(ColumnHeaderStyleProperty, value);
            }
        }

        public DataGridColumnCollection Columns
        {
            get
            {
                return this.Model.Columns;
            }
        }

        public DataGridLength ColumnWidth
        {
            get
            {
                return (DataGridLength)base.GetValue(ColumnWidthProperty);
            }
            set
            {
                base.SetValue(ColumnWidthProperty, value);
            }
        }

        public DataGridCell CurrentCell
        {
            get
            {
                if (this.Model != null)
                {
                    return this.Model.FocusAndEditingManager.CurrentCell;
                }
                return null;
            }
            set
            {
                if (this.Model != null)
                {
                    this.Model.SetCurrentCell(value);
                }
            }
        }

        public DataGridColumn CurrentColumn
        {
            get
            {
                return (DataGridColumn)base.GetValue(CurrentColumnProperty);
            }
            set
            {
                base.SetValue(CurrentColumnProperty, value);
            }
        }

        public DataGridRow CurrentRow
        {
            get
            {
                return (DataGridRow)base.GetValue(CurrentRowProperty);
            }
            set
            {
                base.SetValue(CurrentRowProperty, value);
            }
        }

        public ICollectionView DataSourceView
        {
            get
            {
                if ((this.Model != null) && (this.Model.DataConnection != null))
                {
                    return (this.Model.DataConnection.DataSource as ICollectionView);
                }
                return null;
            }
        }

        public Style DragOverColumnStyle
        {
            get
            {
                return (Style)base.GetValue(DragOverColumnStyleProperty);
            }
            set
            {
                base.SetValue(DragOverColumnStyleProperty, value);
            }
        }

        public Style DragSourceColumnStyle
        {
            get
            {
                return (Style)base.GetValue(DragSourceColumnStyleProperty);
            }
            set
            {
                base.SetValue(DragSourceColumnStyleProperty, value);
            }
        }

        public Style DropIndicatorStyle
        {
            get
            {
                return (Style)base.GetValue(DropIndicatorStyleProperty);
            }
            set
            {
                base.SetValue(DropIndicatorStyleProperty, value);
            }
        }

        public DataGridColumn[] FilteredColumns
        {
            get
            {
                return this.Model.FilterManager.FilteredColumns;
            }
        }

        public DataGridFilterCombination FiltersCombination
        {
            get
            {
                return (DataGridFilterCombination)base.GetValue(FiltersCombinationProperty);
            }
            set
            {
                base.SetValue(FiltersCombinationProperty, value);
            }
        }

        public Style FilterStyle
        {
            get
            {
                return (Style)base.GetValue(FilterStyleProperty);
            }
            set
            {
                base.SetValue(FilterStyleProperty, value);
            }
        }

        public bool Focused { get; private set; }

        public Style FocusStyle
        {
            get
            {
                return (Style)base.GetValue(FocusStyleProperty);
            }
            set
            {
                base.SetValue(FocusStyleProperty, value);
            }
        }

        internal bool ForceMouseOver
        {
            get
            {
                return (bool)base.GetValue(ForceMouseOverProperty);
            }
            set
            {
                base.SetValue(ForceMouseOverProperty, value);
            }
        }

        public int FrozenBottomRowsCount
        {
            get
            {
                return (int)base.GetValue(FrozenBottomRowsCountProperty);
            }
            set
            {
                base.SetValue(FrozenBottomRowsCountProperty, value);
            }
        }

        public int FrozenColumnCount
        {
            get
            {
                return (int)base.GetValue(FrozenColumnCountProperty);
            }
            set
            {
                base.SetValue(FrozenColumnCountProperty, value);
            }
        }

        public int FrozenTopRowsCount
        {
            get
            {
                return (int)base.GetValue(FrozenTopRowsCountProperty);
            }
            set
            {
                base.SetValue(FrozenTopRowsCountProperty, value);
            }
        }

        public DataGridGridLinesVisibility GridLinesVisibility
        {
            get
            {
                return (DataGridGridLinesVisibility)base.GetValue(GridLinesVisibilityProperty);
            }
            set
            {
                base.SetValue(GridLinesVisibilityProperty, value);
            }
        }

        public Style GroupColumnHeaderStyle
        {
            get
            {
                return (Style)base.GetValue(GroupColumnHeaderStyleProperty);
            }
            set
            {
                base.SetValue(GroupColumnHeaderStyleProperty, value);
            }
        }

        public DataGridColumn[] GroupedColumns
        {
            get
            {
                return this.Model.GroupManager.GroupedColumns;
            }
        }

        public Brush GroupingPanelBackground
        {
            get
            {
                return (Brush)base.GetValue(GroupingPanelBackgroundProperty);
            }
            set
            {
                base.SetValue(GroupingPanelBackgroundProperty, value);
            }
        }

        public Brush GroupingPanelForeground
        {
            get
            {
                return (Brush)base.GetValue(GroupingPanelForegroundProperty);
            }
            set
            {
                base.SetValue(GroupingPanelForegroundProperty, value);
            }
        }

        public Style GroupingPanelStyle
        {
            get
            {
                return (Style)base.GetValue(GroupingPanelStyleProperty);
            }
            set
            {
                base.SetValue(GroupingPanelStyleProperty, value);
            }
        }

        public Style GroupRowHeaderStyle
        {
            get
            {
                return (Style)base.GetValue(GroupRowHeaderStyleProperty);
            }
            set
            {
                base.SetValue(GroupRowHeaderStyleProperty, value);
            }
        }

        public DataGridLength GroupRowHeight
        {
            get
            {
                return (DataGridLength)base.GetValue(GroupRowHeightProperty);
            }
            set
            {
                base.SetValue(GroupRowHeightProperty, value);
            }
        }

        public DataGridGroupRowPosition GroupRowPosition
        {
            get
            {
                return (DataGridGroupRowPosition)base.GetValue(GroupRowPositionProperty);
            }
            set
            {
                base.SetValue(GroupRowPositionProperty, value);
            }
        }

        public Style GroupRowStyle
        {
            get
            {
                return (Style)base.GetValue(GroupRowStyleProperty);
            }
            set
            {
                base.SetValue(GroupRowStyleProperty, value);
            }
        }

        public Brush HeaderBackground
        {
            get
            {
                return (Brush)base.GetValue(HeaderBackgroundProperty);
            }
            set
            {
                base.SetValue(HeaderBackgroundProperty, value);
            }
        }

        public Brush HeaderForeground
        {
            get
            {
                return (Brush)base.GetValue(HeaderForegroundProperty);
            }
            set
            {
                base.SetValue(HeaderForegroundProperty, value);
            }
        }

        public DataGridHeadersVisibility HeadersVisibility
        {
            get
            {
                return (DataGridHeadersVisibility)base.GetValue(HeadersVisibilityProperty);
            }
            set
            {
                base.SetValue(HeadersVisibilityProperty, value);
            }
        }

        public Brush HorizontalGridLinesBrush
        {
            get
            {
                return (Brush)base.GetValue(HorizontalGridLinesBrushProperty);
            }
            set
            {
                base.SetValue(HorizontalGridLinesBrushProperty, value);
            }
        }

        public ScrollBarVisibility HorizontalScrollBarVisibility
        {
            get
            {
                return (ScrollBarVisibility)base.GetValue(HorizontalScrollBarVisibilityProperty);
            }
            set
            {
                base.SetValue(HorizontalScrollBarVisibilityProperty, value);
            }
        }

        public double IndentWidth
        {
            get
            {
                return (double)base.GetValue(IndentWidthProperty);
            }
            set
            {
                base.SetValue(IndentWidthProperty, value);
            }
        }

        public bool IsAddingNewRowsAllowed
        {
            get
            {
                return ((this.IsEditingRowsAllowed && (((this.Model == null) || (this.Model.DataConnection == null)) || this.Model.DataConnection.AllowAdd)) && !this.IsReadOnly);
            }
        }

        public bool IsDetailsTogglingAllowed
        {
            get
            {
                return (this.RowDetailsTemplate != null);
            }
        }

        public bool IsEditingRowsAllowed
        {
            get
            {
                return (((((this.Model == null) || (this.Model.DataConnection == null)) || this.Model.DataConnection.AllowEdit) && !this.IsReadOnly) && this.CanUserEditRows);
            }
        }

        public bool IsFilteringRowsAllowed
        {
            get
            {
                if ((this.Model != null) && (this.Model.DataConnection != null))
                {
                    return this.Model.DataConnection.AllowFilter;
                }
                return true;
            }
        }

        public bool IsGroupingRowsAllowed
        {
            get
            {
                if ((this.Model != null) && (this.Model.DataConnection != null))
                {
                    return this.Model.DataConnection.AllowGroup;
                }
                return true;
            }
        }

        public bool IsLoading
        {
            get
            {
                return (bool)base.GetValue(IsLoadingProperty);
            }
            set
            {
                base.SetValue(IsLoadingProperty, value);
            }
        }

        public bool IsMouseOver
        {
            get
            {
                return (bool)base.GetValue(IsMouseOverProperty);
            }
            internal set
            {
                base.SetValue(IsMouseOverProperty, value);
            }
        }

        public bool IsReadOnly
        {
            get
            {
                return (bool)base.GetValue(IsReadOnlyProperty);
            }
            set
            {
                base.SetValue(IsReadOnlyProperty, value);
            }
        }

        public bool IsRemovingRowsAllowed
        {
            get
            {
                return ((((this.Model == null) || (this.Model.DataConnection == null)) || this.Model.DataConnection.AllowRemove) && !this.IsReadOnly);
            }
        }

        public bool IsSortingRowsAllowed
        {
            get
            {
                if ((this.Model != null) && (this.Model.DataConnection != null))
                {
                    return this.Model.DataConnection.AllowSort;
                }
                return true;
            }
        }

        public DataGridCell this[int rowIndex, int columnIndex]
        {
            get
            {
                return this.GetCell(rowIndex, columnIndex);
            }
        }

        public DataGridCell this[DataGridRow row, DataGridColumn column]
        {
            get
            {
                if (((row != null) && (column != null)) && (this.Model != null))
                {
                    return this.Model.GetCell(row, column);
                }
                return null;
            }
        }

        public IEnumerable ItemsSource
        {
            get
            {
                return (IEnumerable)base.GetValue(ItemsSourceProperty);
            }
            set
            {
                base.SetValue(ItemsSourceProperty, value);
            }
        }

        public DataGridLength LeadingColumnWidth
        {
            get
            {
                return (DataGridLength)base.GetValue(LeadingColumnWidthProperty);
            }
            set
            {
                base.SetValue(LeadingColumnWidthProperty, value);
            }
        }

        public double MaxColumnWidth
        {
            get
            {
                return (double)base.GetValue(MaxColumnWidthProperty);
            }
            set
            {
                base.SetValue(MaxColumnWidthProperty, value);
            }
        }

        public double MaxRowHeight
        {
            get
            {
                return (double)base.GetValue(MaxRowHeightProperty);
            }
            set
            {
                base.SetValue(MaxRowHeightProperty, value);
            }
        }

        internal EventHandler<DataGridMergingCellsEventArgs> MergingCellsDelegate
        {
            get
            {
                return this.MergingCells;
            }
        }

        public double MinColumnWidth
        {
            get
            {
                return (double)base.GetValue(MinColumnWidthProperty);
            }
            set
            {
                base.SetValue(MinColumnWidthProperty, value);
            }
        }

        public double MinRowHeight
        {
            get
            {
                return (double)base.GetValue(MinRowHeightProperty);
            }
            set
            {
                base.SetValue(MinRowHeightProperty, value);
            }
        }

        internal DataGridModel Model { get; set; }

        public Brush MouseOverBrush
        {
            get
            {
                return (Brush)base.GetValue(MouseOverBrushProperty);
            }
            set
            {
                base.SetValue(MouseOverBrushProperty, value);
            }
        }

        public Style NewRowHeaderStyle
        {
            get
            {
                return (Style)base.GetValue(NewRowHeaderStyleProperty);
            }
            set
            {
                base.SetValue(NewRowHeaderStyleProperty, value);
            }
        }

        public Style NewRowStyle
        {
            get
            {
                return (Style)base.GetValue(NewRowStyleProperty);
            }
            set
            {
                base.SetValue(NewRowStyleProperty, value);
            }
        }

        public DataGridNewRowVisibility NewRowVisibility
        {
            get
            {
                return (DataGridNewRowVisibility)base.GetValue(NewRowVisibilityProperty);
            }
            set
            {
                base.SetValue(NewRowVisibilityProperty, value);
            }
        }

        public Brush PressedBrush
        {
            get
            {
                return (Brush)base.GetValue(PressedBrushProperty);
            }
            set
            {
                base.SetValue(PressedBrushProperty, value);
            }
        }

        public Brush RowBackground
        {
            get
            {
                return (Brush)base.GetValue(RowBackgroundProperty);
            }
            set
            {
                base.SetValue(RowBackgroundProperty, value);
            }
        }

        public DataTemplate RowDetailsTemplate
        {
            get
            {
                return (DataTemplate)base.GetValue(RowDetailsTemplateProperty);
            }
            set
            {
                base.SetValue(RowDetailsTemplateProperty, value);
            }
        }

        public DataGridRowDetailsVisibilityMode RowDetailsVisibilityMode
        {
            get
            {
                return (DataGridRowDetailsVisibilityMode)base.GetValue(RowDetailsVisibilityModeProperty);
            }
            set
            {
                base.SetValue(RowDetailsVisibilityModeProperty, value);
            }
        }

        public Brush RowForeground
        {
            get
            {
                return (Brush)base.GetValue(RowForegroundProperty);
            }
            set
            {
                base.SetValue(RowForegroundProperty, value);
            }
        }

        public Style RowHeaderStyle
        {
            get
            {
                return (Style)base.GetValue(RowHeaderStyleProperty);
            }
            set
            {
                base.SetValue(RowHeaderStyleProperty, value);
            }
        }

        public double RowHeaderWidth
        {
            get
            {
                return (double)base.GetValue(RowHeaderWidthProperty);
            }
            set
            {
                base.SetValue(RowHeaderWidthProperty, value);
            }
        }

        public DataGridLength RowHeight
        {
            get
            {
                return (DataGridLength)base.GetValue(RowHeightProperty);
            }
            set
            {
                base.SetValue(RowHeightProperty, value);
            }
        }

        public DataGridRowCollection Rows
        {
            get
            {
                if (this.Model != null)
                {
                    return this.Model.Rows;
                }
                return null;
            }
        }

        public Style RowStyle
        {
            get
            {
                return (Style)base.GetValue(RowStyleProperty);
            }
            set
            {
                base.SetValue(RowStyleProperty, value);
            }
        }

        public Style ScrollBarStyle
        {
            get
            {
                return (Style)base.GetValue(ScrollBarStyleProperty);
            }
            set
            {
                base.SetValue(ScrollBarStyleProperty, value);
            }
        }

        public DataGridScrollMode ScrollMode
        {
            get
            {
                return (DataGridScrollMode)base.GetValue(ScrollModeProperty);
            }
            set
            {
                base.SetValue(ScrollModeProperty, value);
            }
        }

        public DataTemplate ScrollPreviewRowTemplate
        {
            get
            {
                return (DataTemplate)base.GetValue(ScrollPreviewRowTemplateProperty);
            }
            set
            {
                base.SetValue(ScrollPreviewRowTemplateProperty, value);
            }
        }

        public Brush SelectedBackground
        {
            get
            {
                return (Brush)base.GetValue(SelectedBackgroundProperty);
            }
            set
            {
                base.SetValue(SelectedBackgroundProperty, value);
            }
        }

        public int SelectedIndex
        {
            get
            {
                return (int)base.GetValue(SelectedIndexProperty);
            }
            set
            {
                base.SetValue(SelectedIndexProperty, value);
            }
        }

        public object SelectedItem
        {
            get
            {
                return base.GetValue(SelectedItemProperty);
            }
            set
            {
                base.SetValue(SelectedItemProperty, value);
            }
        }

        public object[] SelectedItems
        {
            get
            {
                return (from row in this.Selection.SelectedRows
                        where row.Type == DataGridRowType.Item
                        select row.DataItem).ToArray<object>();
            }
        }

        public DataGridSelection Selection
        {
            get
            {
                return this.Model.SelectionManager.Selection;
            }
        }

        public DataGridSelectionMode SelectionMode
        {
            get
            {
                return (DataGridSelectionMode)base.GetValue(SelectionModeProperty);
            }
            set
            {
                base.SetValue(SelectionModeProperty, value);
            }
        }

        public bool ShowFluidMouseOver
        {
            get
            {
                return (bool)base.GetValue(ShowFluidMouseOverProperty);
            }
            set
            {
                base.SetValue(ShowFluidMouseOverProperty, value);
            }
        }

        public bool ShowGroupingPanel
        {
            get
            {
                return (bool)base.GetValue(ShowGroupingPanelProperty);
            }
            set
            {
                base.SetValue(ShowGroupingPanelProperty, value);
            }
        }

        internal bool ShowLeftFreezingSeparator
        {
            get
            {
                return (((this.ShowVerticalFreezingSeparator | this.CanUserFreezeColumns) & DataGridColumnFreezing.Left) == DataGridColumnFreezing.Left);
            }
        }

        public bool ShowValidationIndicators
        {
            get
            {
                return (bool)base.GetValue(ShowValidationIndicatorsProperty);
            }
            set
            {
                base.SetValue(ShowValidationIndicatorsProperty, value);
            }
        }

        public DataGridColumnFreezing ShowVerticalFreezingSeparator
        {
            get
            {
                return (DataGridColumnFreezing)base.GetValue(ShowVerticalFreezingSeparatorProperty);
            }
            set
            {
                base.SetValue(ShowVerticalFreezingSeparatorProperty, value);
            }
        }

        public DataGridColumn[] SortedColumns
        {
            get
            {
                return this.Model.SortManager.SortedColumns;
            }
        }

        public Collection<DataGridRow> TopRows
        {
            get
            {
                return this.Rows.TopRows;
            }
        }

        public Brush ValidationBackground
        {
            get
            {
                return (Brush)base.GetValue(ValidationBackgroundProperty);
            }
            set
            {
                base.SetValue(ValidationBackgroundProperty, value);
            }
        }

        public Brush ValidationForeground
        {
            get
            {
                return (Brush)base.GetValue(ValidationForegroundProperty);
            }
            set
            {
                base.SetValue(ValidationForegroundProperty, value);
            }
        }

        public Style VerticalFreezingSeparatorStyle
        {
            get
            {
                return (Style)base.GetValue(VerticalFreezingSeparatorStyleProperty);
            }
            set
            {
                base.SetValue(VerticalFreezingSeparatorStyleProperty, value);
            }
        }

        public double VerticalFreezingSeparatorWidth
        {
            get
            {
                return (double)base.GetValue(VerticalFreezingSeparatorWidthProperty);
            }
            set
            {
                base.SetValue(VerticalFreezingSeparatorWidthProperty, value);
            }
        }

        public Brush VerticalGridLinesBrush
        {
            get
            {
                return (Brush)base.GetValue(VerticalGridLinesBrushProperty);
            }
            set
            {
                base.SetValue(VerticalGridLinesBrushProperty, value);
            }
        }

        public ScrollBarVisibility VerticalScrollBarVisibility
        {
            get
            {
                return (ScrollBarVisibility)base.GetValue(VerticalScrollBarVisibilityProperty);
            }
            set
            {
                base.SetValue(VerticalScrollBarVisibilityProperty, value);
            }
        }

        public DataGridScrollStep VerticalScrollStep
        {
            get
            {
                return (DataGridScrollStep)base.GetValue(VerticalScrollStepProperty);
            }
            set
            {
                base.SetValue(VerticalScrollStepProperty, value);
            }
        }

        internal DataGridView View { get; set; }

        public DataGridViewport Viewport
        {
            get
            {
                if ((this.View != null) && this.View.IsLoaded)
                {
                    return this.View.Viewport;
                }
                return null;
            }
        }
    }
}
